mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 16:29:51 +03:00
formatting
This commit is contained in:
@@ -14,27 +14,44 @@ export interface MessageBoxProps extends BoxProps {
|
||||
message: string;
|
||||
}
|
||||
|
||||
const LEVEL_ICONS: { [type in MessageBoxLevel]: React.ComponentType<SvgIconProps> } = {
|
||||
const LEVEL_ICONS: {
|
||||
[type in MessageBoxLevel]: React.ComponentType<SvgIconProps>;
|
||||
} = {
|
||||
success: CheckCircleOutlineOutlinedIcon,
|
||||
info: InfoOutlinedIcon,
|
||||
warning: ReportProblemOutlinedIcon,
|
||||
error: ErrorIcon
|
||||
};
|
||||
|
||||
const LEVEL_BACKGROUNDS: { [type in MessageBoxLevel]: (theme: Theme) => string } = {
|
||||
const LEVEL_BACKGROUNDS: {
|
||||
[type in MessageBoxLevel]: (theme: Theme) => string;
|
||||
} = {
|
||||
success: (theme: Theme) => theme.palette.success.dark,
|
||||
info: (theme: Theme) => theme.palette.info.main,
|
||||
warning: (theme: Theme) => theme.palette.warning.dark,
|
||||
error: (theme: Theme) => theme.palette.error.dark
|
||||
};
|
||||
|
||||
const MessageBox: FC<MessageBoxProps> = ({ level, message, sx, children, ...rest }) => {
|
||||
const MessageBox: FC<MessageBoxProps> = ({
|
||||
level,
|
||||
message,
|
||||
sx,
|
||||
children,
|
||||
...rest
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const Icon = LEVEL_ICONS[level];
|
||||
const backgroundColor = LEVEL_BACKGROUNDS[level](theme);
|
||||
const color = 'white';
|
||||
return (
|
||||
<Box p={2} display="flex" alignItems="center" borderRadius={1} sx={{ backgroundColor, color, ...sx }} {...rest}>
|
||||
<Box
|
||||
p={2}
|
||||
display="flex"
|
||||
alignItems="center"
|
||||
borderRadius={1}
|
||||
sx={{ backgroundColor, color, ...sx }}
|
||||
{...rest}
|
||||
>
|
||||
<Icon />
|
||||
<Typography sx={{ ml: 2, flexGrow: 1 }} variant="body1">
|
||||
{message}
|
||||
|
||||
@@ -14,7 +14,16 @@ const SectionContent: FC<SectionContentProps> = (props) => {
|
||||
return (
|
||||
<Paper id={id} sx={{ p: 2, m: 2 }}>
|
||||
{title && (
|
||||
<Divider sx={{ pb: 2, borderColor: 'primary.main', fontSize: 20, color: 'primary.main' }}>{title}</Divider>
|
||||
<Divider
|
||||
sx={{
|
||||
pb: 2,
|
||||
borderColor: 'primary.main',
|
||||
fontSize: 20,
|
||||
color: 'primary.main'
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</Divider>
|
||||
)}
|
||||
{children}
|
||||
</Paper>
|
||||
|
||||
@@ -10,7 +10,10 @@ import type { ValidatedTextFieldProps } from './ValidatedTextField';
|
||||
|
||||
type ValidatedPasswordFieldProps = Omit<ValidatedTextFieldProps, 'type'>;
|
||||
|
||||
const ValidatedPasswordField: FC<ValidatedPasswordFieldProps> = ({ InputProps, ...props }) => {
|
||||
const ValidatedPasswordField: FC<ValidatedPasswordFieldProps> = ({
|
||||
InputProps,
|
||||
...props
|
||||
}) => {
|
||||
const [showPassword, setShowPassword] = useState<boolean>(false);
|
||||
|
||||
return (
|
||||
|
||||
@@ -12,9 +12,14 @@ interface ValidatedFieldProps {
|
||||
|
||||
export type ValidatedTextFieldProps = ValidatedFieldProps & TextFieldProps;
|
||||
|
||||
const ValidatedTextField: FC<ValidatedTextFieldProps> = ({ fieldErrors, ...rest }) => {
|
||||
const ValidatedTextField: FC<ValidatedTextFieldProps> = ({
|
||||
fieldErrors,
|
||||
...rest
|
||||
}) => {
|
||||
const errors = fieldErrors && fieldErrors[rest.name];
|
||||
const renderErrors = () => errors && errors.map((e, i) => <FormHelperText key={i}>{e.message}</FormHelperText>);
|
||||
const renderErrors = () =>
|
||||
errors &&
|
||||
errors.map((e, i) => <FormHelperText key={i}>{e.message}</FormHelperText>);
|
||||
return (
|
||||
<>
|
||||
<TextField error={!!errors} {...rest} />
|
||||
|
||||
@@ -21,7 +21,12 @@ const LayoutAppBar: FC<LayoutAppBarProps> = ({ title, onToggleDrawer }) => (
|
||||
}}
|
||||
>
|
||||
<Toolbar>
|
||||
<IconButton color="inherit" edge="start" onClick={onToggleDrawer} sx={{ mr: 2, display: { md: 'none' } }}>
|
||||
<IconButton
|
||||
color="inherit"
|
||||
edge="start"
|
||||
onClick={onToggleDrawer}
|
||||
sx={{ mr: 2, display: { md: 'none' } }}
|
||||
>
|
||||
<MenuIcon />
|
||||
</IconButton>
|
||||
<Typography variant="h6" noWrap component="div">
|
||||
|
||||
@@ -54,7 +54,9 @@ const LayoutMenu: FC = () => {
|
||||
|
||||
const [menuOpen, setMenuOpen] = useState(true);
|
||||
|
||||
const onLocaleSelected: ChangeEventHandler<HTMLInputElement> = async ({ target }) => {
|
||||
const onLocaleSelected: ChangeEventHandler<HTMLInputElement> = async ({
|
||||
target
|
||||
}) => {
|
||||
const loc = target.value as Locales;
|
||||
localStorage.setItem('lang', loc);
|
||||
await loadLocaleAsync(loc);
|
||||
@@ -98,7 +100,14 @@ const LayoutMenu: FC = () => {
|
||||
mb: '2px',
|
||||
color: 'lightblue'
|
||||
}}
|
||||
secondary={LL.CUSTOMIZATIONS() + ', ' + LL.SCHEDULER() + ', ' + LL.CUSTOM_ENTITIES(0) + '...'}
|
||||
secondary={
|
||||
LL.CUSTOMIZATIONS() +
|
||||
', ' +
|
||||
LL.SCHEDULER() +
|
||||
', ' +
|
||||
LL.CUSTOM_ENTITIES(0) +
|
||||
'...'
|
||||
}
|
||||
secondaryTypographyProps={{
|
||||
noWrap: true,
|
||||
fontSize: 12,
|
||||
@@ -123,7 +132,12 @@ const LayoutMenu: FC = () => {
|
||||
disabled={!me.admin}
|
||||
to={`/customizations`}
|
||||
/>
|
||||
<LayoutMenuItem icon={MoreTimeIcon} label={LL.SCHEDULER()} disabled={!me.admin} to={`/scheduler`} />
|
||||
<LayoutMenuItem
|
||||
icon={MoreTimeIcon}
|
||||
label={LL.SCHEDULER()}
|
||||
disabled={!me.admin}
|
||||
to={`/scheduler`}
|
||||
/>
|
||||
<LayoutMenuItem
|
||||
icon={PlaylistAddIcon}
|
||||
label={LL.CUSTOM_ENTITIES(0)}
|
||||
@@ -137,7 +151,12 @@ const LayoutMenu: FC = () => {
|
||||
|
||||
<List style={{ marginTop: `auto` }}>
|
||||
<LayoutMenuItem icon={AssessmentIcon} label={LL.SYSTEM(0)} to="/system" />
|
||||
<LayoutMenuItem icon={SettingsIcon} label={LL.SETTINGS(0)} disabled={!me.admin} to="/settings" />
|
||||
<LayoutMenuItem
|
||||
icon={SettingsIcon}
|
||||
label={LL.SETTINGS(0)}
|
||||
disabled={!me.admin}
|
||||
to="/settings"
|
||||
/>
|
||||
<LayoutMenuItem icon={LiveHelpIcon} label={LL.HELP_OF('')} to={`/help`} />
|
||||
</List>
|
||||
<Divider />
|
||||
@@ -239,7 +258,12 @@ const LayoutMenu: FC = () => {
|
||||
</TextField>
|
||||
</Box>
|
||||
<Box>
|
||||
<Button variant="outlined" fullWidth color="primary" onClick={() => signOut(true)}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
color="primary"
|
||||
onClick={() => signOut(true)}
|
||||
>
|
||||
{LL.SIGN_OUT()}
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
@@ -13,7 +13,12 @@ interface LayoutMenuItemProps {
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
const LayoutMenuItem: FC<LayoutMenuItemProps> = ({ icon: Icon, label, to, disabled }) => {
|
||||
const LayoutMenuItem: FC<LayoutMenuItemProps> = ({
|
||||
icon: Icon,
|
||||
label,
|
||||
to,
|
||||
disabled
|
||||
}) => {
|
||||
const { pathname } = useLocation();
|
||||
|
||||
const selected = routeMatches(to, pathname);
|
||||
@@ -23,7 +28,9 @@ const LayoutMenuItem: FC<LayoutMenuItemProps> = ({ icon: Icon, label, to, disabl
|
||||
<ListItemIcon sx={{ color: selected ? '#90caf9' : '#9e9e9e' }}>
|
||||
<Icon />
|
||||
</ListItemIcon>
|
||||
<ListItemText sx={{ color: selected ? '#90caf9' : '#f5f5f5' }}>{label}</ListItemText>
|
||||
<ListItemText sx={{ color: selected ? '#90caf9' : '#f5f5f5' }}>
|
||||
{label}
|
||||
</ListItemText>
|
||||
</ListItemButton>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2,7 +2,14 @@ import type { FC } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import NavigateNextIcon from '@mui/icons-material/NavigateNext';
|
||||
import { Avatar, ListItem, ListItemAvatar, ListItemButton, ListItemIcon, ListItemText } from '@mui/material';
|
||||
import {
|
||||
Avatar,
|
||||
ListItem,
|
||||
ListItemAvatar,
|
||||
ListItemButton,
|
||||
ListItemIcon,
|
||||
ListItemText
|
||||
} from '@mui/material';
|
||||
import type { SvgIconProps } from '@mui/material';
|
||||
|
||||
interface ListMenuItemProps {
|
||||
@@ -27,19 +34,38 @@ function RenderIcon({ icon: Icon, bgcolor, label, text }: ListMenuItemProps) {
|
||||
);
|
||||
}
|
||||
|
||||
const LayoutMenuItem: FC<ListMenuItemProps> = ({ icon, bgcolor, label, text, to, disabled }) => (
|
||||
const LayoutMenuItem: FC<ListMenuItemProps> = ({
|
||||
icon,
|
||||
bgcolor,
|
||||
label,
|
||||
text,
|
||||
to,
|
||||
disabled
|
||||
}) => (
|
||||
<>
|
||||
{to && !disabled ? (
|
||||
<ListItem
|
||||
disablePadding
|
||||
secondaryAction={
|
||||
<ListItemIcon style={{ justifyContent: 'right', color: 'lightblue', verticalAlign: 'middle' }}>
|
||||
<ListItemIcon
|
||||
style={{
|
||||
justifyContent: 'right',
|
||||
color: 'lightblue',
|
||||
verticalAlign: 'middle'
|
||||
}}
|
||||
>
|
||||
<NavigateNextIcon />
|
||||
</ListItemIcon>
|
||||
}
|
||||
>
|
||||
<ListItemButton component={Link} to={to}>
|
||||
<RenderIcon icon={icon} bgcolor={bgcolor} label={label} text={text} to="" />
|
||||
<RenderIcon
|
||||
icon={icon}
|
||||
bgcolor={bgcolor}
|
||||
label={label}
|
||||
text={text}
|
||||
to=""
|
||||
/>
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
) : (
|
||||
|
||||
@@ -22,7 +22,13 @@ const ApplicationError: FC<ApplicationErrorProps> = ({ message }) => (
|
||||
borderRadius: 0
|
||||
}}
|
||||
>
|
||||
<Box display="flex" flexDirection="row" justifyContent="center" alignItems="center" mb={2}>
|
||||
<Box
|
||||
display="flex"
|
||||
flexDirection="row"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
mb={2}
|
||||
>
|
||||
<WarningIcon fontSize="large" color="error" />
|
||||
<Box ml={2}>
|
||||
<Typography variant="h4">Application Error</Typography>
|
||||
|
||||
@@ -12,14 +12,23 @@ interface FormLoaderProps {
|
||||
onRetry?: () => void;
|
||||
}
|
||||
|
||||
const FormLoader: FC<FormLoaderProps> = ({ errorMessage, onRetry, message = 'Loading…' }) => {
|
||||
const FormLoader: FC<FormLoaderProps> = ({
|
||||
errorMessage,
|
||||
onRetry,
|
||||
message = 'Loading…'
|
||||
}) => {
|
||||
const { LL } = useI18nContext();
|
||||
|
||||
if (errorMessage) {
|
||||
return (
|
||||
<MessageBox my={2} level="error" message={errorMessage}>
|
||||
{onRetry && (
|
||||
<Button startIcon={<RefreshIcon />} variant="contained" color="error" onClick={onRetry}>
|
||||
<Button
|
||||
startIcon={<RefreshIcon />}
|
||||
variant="contained"
|
||||
color="error"
|
||||
onClick={onRetry}
|
||||
>
|
||||
{LL.RETRY()}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
@@ -13,7 +13,14 @@ const LoadingSpinner: FC<LoadingSpinnerProps> = ({ height = '100%' }) => {
|
||||
const { LL } = useI18nContext();
|
||||
|
||||
return (
|
||||
<Box display="flex" alignItems="center" justifyContent="center" flexDirection="column" padding={2} height={height}>
|
||||
<Box
|
||||
display="flex"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
flexDirection="column"
|
||||
padding={2}
|
||||
height={height}
|
||||
>
|
||||
<CircularProgress
|
||||
sx={(theme: Theme) => ({
|
||||
margin: theme.spacing(4),
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
import type { FC } from 'react';
|
||||
import type { Blocker } from 'react-router-dom';
|
||||
|
||||
import { Button, Dialog, DialogActions, DialogContent, DialogTitle } from '@mui/material';
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogTitle
|
||||
} from '@mui/material';
|
||||
|
||||
import { dialogStyle } from 'CustomTheme';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
@@ -18,10 +24,18 @@ const BlockNavigation: FC<BlockNavigationProps> = ({ blocker }) => {
|
||||
<DialogTitle>{LL.BLOCK_NAVIGATE_1()}</DialogTitle>
|
||||
<DialogContent dividers>{LL.BLOCK_NAVIGATE_2()}</DialogContent>
|
||||
<DialogActions>
|
||||
<Button variant="outlined" onClick={() => blocker.reset?.()} color="secondary">
|
||||
<Button
|
||||
variant="outlined"
|
||||
onClick={() => blocker.reset?.()}
|
||||
color="secondary"
|
||||
>
|
||||
{LL.STAY()}
|
||||
</Button>
|
||||
<Button variant="contained" onClick={() => blocker.proceed?.()} color="primary">
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={() => blocker.proceed?.()}
|
||||
color="primary"
|
||||
>
|
||||
{LL.LEAVE()}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
|
||||
@@ -7,7 +7,11 @@ import type { RequiredChildrenProps } from 'utils';
|
||||
|
||||
const RequireAdmin: FC<RequiredChildrenProps> = ({ children }) => {
|
||||
const authenticatedContext = useContext(AuthenticatedContext);
|
||||
return authenticatedContext.me.admin ? <>{children}</> : <Navigate replace to="/" />;
|
||||
return authenticatedContext.me.admin ? (
|
||||
<>{children}</>
|
||||
) : (
|
||||
<Navigate replace to="/" />
|
||||
);
|
||||
};
|
||||
|
||||
export default RequireAdmin;
|
||||
|
||||
@@ -5,7 +5,10 @@ import { Navigate, useLocation } from 'react-router-dom';
|
||||
import { storeLoginRedirect } from 'api/authentication';
|
||||
|
||||
import type { AuthenticatedContextValue } from 'contexts/authentication/context';
|
||||
import { AuthenticatedContext, AuthenticationContext } from 'contexts/authentication/context';
|
||||
import {
|
||||
AuthenticatedContext,
|
||||
AuthenticationContext
|
||||
} from 'contexts/authentication/context';
|
||||
import type { RequiredChildrenProps } from 'utils';
|
||||
|
||||
const RequireAuthenticated: FC<RequiredChildrenProps> = ({ children }) => {
|
||||
@@ -19,7 +22,9 @@ const RequireAuthenticated: FC<RequiredChildrenProps> = ({ children }) => {
|
||||
});
|
||||
|
||||
return authenticationContext.me ? (
|
||||
<AuthenticatedContext.Provider value={authenticationContext as AuthenticatedContextValue}>
|
||||
<AuthenticatedContext.Provider
|
||||
value={authenticationContext as AuthenticatedContextValue}
|
||||
>
|
||||
{children}
|
||||
</AuthenticatedContext.Provider>
|
||||
) : (
|
||||
|
||||
@@ -10,7 +10,11 @@ import type { RequiredChildrenProps } from 'utils';
|
||||
const RequireUnauthenticated: FC<RequiredChildrenProps> = ({ children }) => {
|
||||
const authenticationContext = useContext(AuthenticationContext);
|
||||
|
||||
return authenticationContext.me ? <Navigate to={AuthenticationApi.fetchLoginRedirect()} /> : <>{children}</>;
|
||||
return authenticationContext.me ? (
|
||||
<Navigate to={AuthenticationApi.fetchLoginRedirect()} />
|
||||
) : (
|
||||
<>{children}</>
|
||||
);
|
||||
};
|
||||
|
||||
export default RequireUnauthenticated;
|
||||
|
||||
@@ -20,7 +20,11 @@ const RouterTabs: FC<RouterTabsProps> = ({ value, children }) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Tabs value={value} onChange={handleTabChange} variant={smallDown ? 'scrollable' : 'fullWidth'}>
|
||||
<Tabs
|
||||
value={value}
|
||||
onChange={handleTabChange}
|
||||
variant={smallDown ? 'scrollable' : 'fullWidth'}
|
||||
>
|
||||
{children}
|
||||
</Tabs>
|
||||
);
|
||||
|
||||
@@ -31,7 +31,12 @@ export interface SingleUploadProps {
|
||||
progress: Progress;
|
||||
}
|
||||
|
||||
const SingleUpload: FC<SingleUploadProps> = ({ onDrop, onCancel, isUploading, progress }) => {
|
||||
const SingleUpload: FC<SingleUploadProps> = ({
|
||||
onDrop,
|
||||
onCancel,
|
||||
isUploading,
|
||||
progress
|
||||
}) => {
|
||||
const uploading = isUploading && progress.total > 0;
|
||||
|
||||
const dropzoneState = useDropzone({
|
||||
@@ -53,8 +58,14 @@ const SingleUpload: FC<SingleUploadProps> = ({ onDrop, onCancel, isUploading, pr
|
||||
if (uploading) {
|
||||
if (progress.total && progress.loaded) {
|
||||
return progress.loaded <= progress.total
|
||||
? LL.UPLOADING() + ': ' + Math.round((progress.loaded * 100) / progress.total) + '%'
|
||||
: LL.UPLOADING() + ': ' + Math.round((progress.total * 100) / progress.loaded) + '%';
|
||||
? LL.UPLOADING() +
|
||||
': ' +
|
||||
Math.round((progress.loaded * 100) / progress.total) +
|
||||
'%'
|
||||
: LL.UPLOADING() +
|
||||
': ' +
|
||||
Math.round((progress.total * 100) / progress.loaded) +
|
||||
'%';
|
||||
}
|
||||
}
|
||||
return LL.UPLOAD_DROP_TEXT();
|
||||
@@ -95,7 +106,12 @@ const SingleUpload: FC<SingleUploadProps> = ({ onDrop, onCancel, isUploading, pr
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
<Button startIcon={<CancelIcon />} variant="outlined" color="secondary" onClick={onCancel}>
|
||||
<Button
|
||||
startIcon={<CancelIcon />}
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
onClick={onCancel}
|
||||
>
|
||||
{LL.CANCEL()}
|
||||
</Button>
|
||||
</Fragment>
|
||||
|
||||
Reference in New Issue
Block a user