Skip to content

Commit

Permalink
Merge pull request #4660 from thornbill/routes-layout-refactor
Browse files Browse the repository at this point in the history
Refactor routes to use layout elements
  • Loading branch information
thornbill authored Jun 8, 2023
2 parents 050d072 + 186dd44 commit 13aa3c9
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 200 deletions.
141 changes: 35 additions & 106 deletions src/apps/experimental/App.tsx
Original file line number Diff line number Diff line change
@@ -1,114 +1,43 @@
import React, { useCallback, useEffect, useState } from 'react';
import AppBar from '@mui/material/AppBar';
import Box from '@mui/material/Box';
import { ThemeProvider } from '@mui/material/styles';
import { useLocation } from 'react-router-dom';
import React from 'react';
import { Navigate, Route, Routes } from 'react-router-dom';

import AppHeader from 'components/AppHeader';
import Backdrop from 'components/Backdrop';
import { useApi } from 'hooks/useApi';
import { useLocalStorage } from 'hooks/useLocalStorage';
import ConnectionRequired from 'components/ConnectionRequired';
import ServerContentPage from 'components/ServerContentPage';
import { toAsyncPageRoute } from 'components/router/AsyncRoute';
import { toViewManagerPageRoute } from 'components/router/LegacyRoute';

import AppToolbar from './components/AppToolbar';
import AppDrawer, { DRAWER_WIDTH, isDrawerPath } from './components/drawers/AppDrawer';
import ElevationScroll from './components/ElevationScroll';
import { ExperimentalAppRoutes } from './routes/AppRoutes';
import theme from './theme';

import './AppOverrides.scss';

interface ExperimentalAppSettings {
isDrawerPinned: boolean
}

const DEFAULT_EXPERIMENTAL_APP_SETTINGS: ExperimentalAppSettings = {
isDrawerPinned: false
};
import AppLayout from './AppLayout';
import { ASYNC_ADMIN_ROUTES, ASYNC_USER_ROUTES } from './routes/asyncRoutes';
import { LEGACY_ADMIN_ROUTES, LEGACY_PUBLIC_ROUTES, LEGACY_USER_ROUTES } from './routes/legacyRoutes';

const ExperimentalApp = () => {
const [ appSettings, setAppSettings ] = useLocalStorage<ExperimentalAppSettings>('ExperimentalAppSettings', DEFAULT_EXPERIMENTAL_APP_SETTINGS);
const [ isDrawerActive, setIsDrawerActive ] = useState(appSettings.isDrawerPinned);
const { user } = useApi();
const location = useLocation();

const isDrawerAvailable = isDrawerPath(location.pathname);
const isDrawerOpen = isDrawerActive && isDrawerAvailable && Boolean(user);

useEffect(() => {
if (isDrawerActive !== appSettings.isDrawerPinned) {
setAppSettings({
...appSettings,
isDrawerPinned: isDrawerActive
});
}
}, [ appSettings, isDrawerActive, setAppSettings ]);

const onToggleDrawer = useCallback(() => {
setIsDrawerActive(!isDrawerActive);
}, [ isDrawerActive, setIsDrawerActive ]);

return (
<ThemeProvider theme={theme}>
<Backdrop />

<div style={{ display: 'none' }}>
{/*
* TODO: These components are not used, but views interact with them directly so the need to be
* present in the dom. We add them in a hidden element to prevent errors.
*/}
<AppHeader />
</div>

<Box sx={{ display: 'flex' }}>
<ElevationScroll elevate={isDrawerOpen}>
<AppBar
position='fixed'
sx={{ zIndex: (muiTheme) => muiTheme.zIndex.drawer + 1 }}
>
<AppToolbar
isDrawerOpen={isDrawerOpen}
onDrawerButtonClick={onToggleDrawer}
/>
</AppBar>
</ElevationScroll>

<AppDrawer
open={isDrawerOpen}
onClose={onToggleDrawer}
onOpen={onToggleDrawer}
/>

<Box
component='main'
sx={{
width: '100%',
flexGrow: 1,
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen
}),
marginLeft: 0,
...(isDrawerAvailable && {
marginLeft: {
sm: `-${DRAWER_WIDTH}px`
}
}),
...(isDrawerActive && {
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen
}),
marginLeft: 0
})
}}
>
<div className='mainAnimatedPages skinBody' />
<div className='skinBody'>
<ExperimentalAppRoutes />
</div>
</Box>
</Box>
</ThemeProvider>
<Routes>
<Route path='/*' element={<AppLayout />}>
{/* User routes */}
<Route element={<ConnectionRequired />}>
{ASYNC_USER_ROUTES.map(toAsyncPageRoute)}
{LEGACY_USER_ROUTES.map(toViewManagerPageRoute)}
</Route>

{/* Admin routes */}
<Route element={<ConnectionRequired isAdminRequired />}>
{ASYNC_ADMIN_ROUTES.map(toAsyncPageRoute)}
{LEGACY_ADMIN_ROUTES.map(toViewManagerPageRoute)}

<Route path='configurationpage' element={
<ServerContentPage view='/web/configurationpage' />
} />
</Route>

{/* Public routes */}
<Route element={<ConnectionRequired isUserRequired={false} />}>
<Route index element={<Navigate replace to='/home.html' />} />

{LEGACY_PUBLIC_ROUTES.map(toViewManagerPageRoute)}
</Route>
</Route>
</Routes>
);
};

Expand Down
114 changes: 114 additions & 0 deletions src/apps/experimental/AppLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import React, { useCallback, useEffect, useState } from 'react';
import AppBar from '@mui/material/AppBar';
import Box from '@mui/material/Box';
import { ThemeProvider } from '@mui/material/styles';
import { Outlet, useLocation } from 'react-router-dom';

import AppHeader from 'components/AppHeader';
import Backdrop from 'components/Backdrop';
import { useApi } from 'hooks/useApi';
import { useLocalStorage } from 'hooks/useLocalStorage';

import AppToolbar from './components/AppToolbar';
import AppDrawer, { DRAWER_WIDTH, isDrawerPath } from './components/drawers/AppDrawer';
import ElevationScroll from './components/ElevationScroll';
import theme from './theme';

import './AppOverrides.scss';

interface ExperimentalAppSettings {
isDrawerPinned: boolean
}

const DEFAULT_EXPERIMENTAL_APP_SETTINGS: ExperimentalAppSettings = {
isDrawerPinned: false
};

const AppLayout = () => {
const [ appSettings, setAppSettings ] = useLocalStorage<ExperimentalAppSettings>('ExperimentalAppSettings', DEFAULT_EXPERIMENTAL_APP_SETTINGS);
const [ isDrawerActive, setIsDrawerActive ] = useState(appSettings.isDrawerPinned);
const { user } = useApi();
const location = useLocation();

const isDrawerAvailable = isDrawerPath(location.pathname);
const isDrawerOpen = isDrawerActive && isDrawerAvailable && Boolean(user);

useEffect(() => {
if (isDrawerActive !== appSettings.isDrawerPinned) {
setAppSettings({
...appSettings,
isDrawerPinned: isDrawerActive
});
}
}, [ appSettings, isDrawerActive, setAppSettings ]);

const onToggleDrawer = useCallback(() => {
setIsDrawerActive(!isDrawerActive);
}, [ isDrawerActive, setIsDrawerActive ]);

return (
<ThemeProvider theme={theme}>
<Backdrop />

<div style={{ display: 'none' }}>
{/*
* TODO: These components are not used, but views interact with them directly so the need to be
* present in the dom. We add them in a hidden element to prevent errors.
*/}
<AppHeader />
</div>

<Box sx={{ display: 'flex' }}>
<ElevationScroll elevate={isDrawerOpen}>
<AppBar
position='fixed'
sx={{ zIndex: (muiTheme) => muiTheme.zIndex.drawer + 1 }}
>
<AppToolbar
isDrawerOpen={isDrawerOpen}
onDrawerButtonClick={onToggleDrawer}
/>
</AppBar>
</ElevationScroll>

<AppDrawer
open={isDrawerOpen}
onClose={onToggleDrawer}
onOpen={onToggleDrawer}
/>

<Box
component='main'
sx={{
width: '100%',
flexGrow: 1,
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen
}),
marginLeft: 0,
...(isDrawerAvailable && {
marginLeft: {
sm: `-${DRAWER_WIDTH}px`
}
}),
...(isDrawerActive && {
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen
}),
marginLeft: 0
})
}}
>
<div className='mainAnimatedPages skinBody' />
<div className='skinBody'>
<Outlet />
</div>
</Box>
</Box>
</ThemeProvider>
);
};

export default AppLayout;
3 changes: 0 additions & 3 deletions src/apps/experimental/components/drawers/AppDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,6 @@ const AppDrawer: FC<ResponsiveDrawerProps> = ({
/>
))
}

{/* Suppress warnings for unhandled routes */}
<Route path='*' element={null} />
</Routes>
);

Expand Down
3 changes: 0 additions & 3 deletions src/apps/experimental/components/tabs/AppTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,6 @@ const AppTabs: FC<AppTabsParams> = ({
/>
))
}

{/* Suppress warnings for unhandled routes */}
<Route path='*' element={null} />
</Routes>
);
};
Expand Down
42 changes: 0 additions & 42 deletions src/apps/experimental/routes/AppRoutes.tsx

This file was deleted.

49 changes: 44 additions & 5 deletions src/apps/stable/App.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,58 @@
import React from 'react';
import { Navigate, Outlet, Route, Routes } from 'react-router-dom';

import AppHeader from '../../components/AppHeader';
import Backdrop from '../../components/Backdrop';
import { AppRoutes } from './routes/AppRoutes';
import AppHeader from 'components/AppHeader';
import Backdrop from 'components/Backdrop';
import ServerContentPage from 'components/ServerContentPage';
import ConnectionRequired from 'components/ConnectionRequired';
import { toAsyncPageRoute } from 'components/router/AsyncRoute';
import { toViewManagerPageRoute } from 'components/router/LegacyRoute';

const StableApp = () => (
import { ASYNC_ADMIN_ROUTES, ASYNC_USER_ROUTES } from './routes/asyncRoutes';
import { LEGACY_ADMIN_ROUTES, LEGACY_PUBLIC_ROUTES, LEGACY_USER_ROUTES } from './routes/legacyRoutes';

const Layout = () => (
<>
<Backdrop />
<AppHeader />

<div className='mainAnimatedPages skinBody' />
<div className='skinBody'>
<AppRoutes />
<Outlet />
</div>
</>
);

const StableApp = () => (
<Routes>
<Route element={<Layout />}>
{/* User routes */}
<Route path='/' element={<ConnectionRequired />}>
{ASYNC_USER_ROUTES.map(toAsyncPageRoute)}
{LEGACY_USER_ROUTES.map(toViewManagerPageRoute)}
</Route>

{/* Admin routes */}
<Route path='/' element={<ConnectionRequired isAdminRequired />}>
{ASYNC_ADMIN_ROUTES.map(toAsyncPageRoute)}
{LEGACY_ADMIN_ROUTES.map(toViewManagerPageRoute)}

<Route path='configurationpage' element={
<ServerContentPage view='/web/configurationpage' />
} />
</Route>

{/* Public routes */}
<Route path='/' element={<ConnectionRequired isUserRequired={false} />}>
<Route index element={<Navigate replace to='/home.html' />} />

{LEGACY_PUBLIC_ROUTES.map(toViewManagerPageRoute)}
</Route>

{/* Suppress warnings for unhandled routes */}
<Route path='*' element={null} />
</Route>
</Routes>
);

export default StableApp;
Loading

0 comments on commit 13aa3c9

Please sign in to comment.