-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
FI-2405: Create skeleton loader for main app (#440)
* create header and footer skeletons * add footer skeleton to test session * create skeleton structure * add classes to skeletons * add skeleton for tree * add session skeleton * add main component back to router * add footer use case * revert gemfile * revert demo * remove footer case --------- Co-authored-by: Alyssa Wang <awang@mitre.org>
- Loading branch information
1 parent
58320f3
commit 54713d5
Showing
8 changed files
with
354 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import React, { FC } from 'react'; | ||
import { Box } from '@mui/material'; | ||
import lightTheme from '~/styles/theme'; | ||
// import { AppBar, Box, Skeleton, Toolbar } from '@mui/material'; | ||
import { useAppStore } from '~/store/app'; | ||
import useStyles from '~/components/TestSuite/styles'; | ||
import DrawerSkeleton from '~/components/Skeletons/DrawerSkeleton'; | ||
import TestSessionSkeleton from '~/components/Skeletons/TestSessionSkeleton'; | ||
|
||
const AppSkeleton: FC<Record<string, never>> = () => { | ||
const { classes } = useStyles(); | ||
const windowIsSmall = useAppStore((state) => state.windowIsSmall); | ||
|
||
return ( | ||
<Box className={classes.testSuiteMain}> | ||
<DrawerSkeleton /> | ||
<main | ||
style={{ | ||
overflow: 'auto', | ||
width: '100%', | ||
backgroundColor: lightTheme.palette.common.grayLightest, | ||
}} | ||
> | ||
<Box className={classes.contentContainer} p={windowIsSmall ? 1 : 4}> | ||
<TestSessionSkeleton /> | ||
</Box> | ||
</main> | ||
</Box> | ||
); | ||
}; | ||
|
||
export default AppSkeleton; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import React, { FC } from 'react'; | ||
import { Box, Divider, Drawer, Skeleton } from '@mui/material'; | ||
import { useAppStore } from '~/store/app'; | ||
import useStylesDrawer from '~/components/TestSuite/styles'; | ||
import useStylesTree from '~/components/TestSuite/TestSuiteTree/styles'; | ||
|
||
const DrawerSkeleton: FC<Record<string, never>> = () => { | ||
const drawerClasses = useStylesDrawer().classes; | ||
const treeClasses = useStylesTree().classes; | ||
const windowIsSmall = useAppStore((state) => state.windowIsSmall); | ||
const skeletonCount = 3; | ||
|
||
const treeItemSkeleton = ( | ||
<Box display="flex" flexDirection="row" alignItems="center" mx={2} my={2}> | ||
<Skeleton variant="circular" height="14px" width="16px" /> | ||
<Skeleton height={10} width={200} sx={{ ml: 1 }} /> | ||
</Box> | ||
); | ||
|
||
const nestedTreeItemSkeleton = <Box ml={3}>{treeItemSkeleton}</Box>; | ||
|
||
const skeletonList = []; | ||
for (let index = 0; index < skeletonCount; index++) { | ||
skeletonList.push( | ||
<div key={index}> | ||
{treeItemSkeleton} | ||
{nestedTreeItemSkeleton} | ||
{nestedTreeItemSkeleton} | ||
</div> | ||
); | ||
} | ||
|
||
return windowIsSmall ? ( | ||
<></> | ||
) : ( | ||
<Drawer variant="permanent" anchor="left" classes={{ paper: drawerClasses.drawerPaper }}> | ||
<Skeleton variant="rounded" height={32} sx={{ m: 2 }} /> | ||
<Divider /> | ||
<Box className={treeClasses.testSuiteTreePanel} py={1}> | ||
{skeletonList} | ||
</Box> | ||
</Drawer> | ||
); | ||
}; | ||
|
||
export default DrawerSkeleton; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import React, { FC } from 'react'; | ||
import { Box, Skeleton } from '@mui/material'; | ||
import { useAppStore } from '~/store/app'; | ||
import useStyles from '~/components/Footer/styles'; | ||
|
||
const FooterSkeleton: FC<Record<string, never>> = () => { | ||
const { classes } = useStyles(); | ||
const footerHeight = useAppStore((state) => state.footerHeight); | ||
const windowIsSmall = useAppStore((state) => state.windowIsSmall); | ||
|
||
return ( | ||
<footer | ||
className={classes.footer} | ||
style={{ | ||
minHeight: `${footerHeight}px`, | ||
maxHeight: `${footerHeight}px`, | ||
backgroundColor: 'white', | ||
}} | ||
> | ||
<Box display="flex" flexDirection="row" justifyContent="space-between" width="100%"> | ||
<Box display="flex" alignItems="center" px={2}> | ||
{windowIsSmall ? ( | ||
<Skeleton variant="rectangular" height={22} width={80} sx={{ mr: 1 }} /> | ||
) : ( | ||
<Skeleton | ||
variant="rectangular" | ||
height={40} | ||
width={100} | ||
style={{ marginRight: '16px' }} | ||
/> | ||
)} | ||
<Box display="flex" flexDirection="column"> | ||
{!windowIsSmall && <Skeleton height={10} width={60} />} | ||
<Skeleton height={20} width={100} /> | ||
</Box> | ||
</Box> | ||
<Box display="flex" alignItems="center" pr={windowIsSmall ? 1 : 3} py={2}> | ||
{windowIsSmall ? ( | ||
<Skeleton variant="circular" height={20} width={20} /> | ||
) : ( | ||
<Skeleton variant="rounded" height={24} width={200} /> | ||
)} | ||
</Box> | ||
</Box> | ||
</footer> | ||
); | ||
}; | ||
|
||
export default FooterSkeleton; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import React, { FC } from 'react'; | ||
import { AppBar, Box, Skeleton, Toolbar } from '@mui/material'; | ||
import { useAppStore } from '~/store/app'; | ||
import useStyles from '~/components/Header/styles'; | ||
|
||
const HeaderSkeleton: FC<Record<string, never>> = () => { | ||
const { classes } = useStyles(); | ||
const headerHeight = useAppStore((state) => state.headerHeight); | ||
const windowIsSmall = useAppStore((state) => state.windowIsSmall); | ||
|
||
return ( | ||
<AppBar | ||
color="default" | ||
className={classes.appbar} | ||
style={{ | ||
minHeight: `${headerHeight}px`, // For responsive screens | ||
maxHeight: `${headerHeight}px`, // For responsive screens | ||
}} | ||
> | ||
<Toolbar className={classes.toolbar}> | ||
{/* Home button */} | ||
<Skeleton variant="circular" height={44} width={44} /> | ||
|
||
{/* Header Text */} | ||
<Box display="flex" flexDirection="column" flexGrow="1" alignSelf="center" py={0.5} pl={2}> | ||
<Skeleton height={35} width="70%" /> | ||
<Skeleton height={15} width="60%" /> | ||
</Box> | ||
|
||
{/* New Session button */} | ||
<Box display="flex" style={windowIsSmall ? { marginRight: '-16px' } : {}}> | ||
{windowIsSmall ? ( | ||
<Skeleton variant="circular" height={32} width={32} sx={{ mr: 1 }} /> | ||
) : ( | ||
<Skeleton variant="rounded" height={30} width={140} /> | ||
)} | ||
</Box> | ||
</Toolbar> | ||
</AppBar> | ||
); | ||
}; | ||
|
||
export default HeaderSkeleton; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import React, { FC } from 'react'; | ||
import { Box, Card, Divider, Skeleton } from '@mui/material'; | ||
import { useAppStore } from '~/store/app'; | ||
import useStyles from '~/components/TestSuite/TestSuiteDetails/styles'; | ||
|
||
const TestSessionSkeleton: FC<Record<string, never>> = () => { | ||
const { classes } = useStyles(); | ||
const windowIsSmall = useAppStore((state) => state.windowIsSmall); | ||
const skeletonCount = 3; | ||
|
||
const expandableItemSkeleton = ( | ||
<> | ||
<Divider /> | ||
<Box | ||
sx={{ | ||
display: 'flex', | ||
alignItems: 'center', | ||
minHeight: '36.5px', | ||
px: 2, | ||
py: 1, | ||
}} | ||
> | ||
<Skeleton variant="circular" height={24} width={24} /> | ||
<span className={classes.testGroupCardHeaderText}> | ||
<Skeleton height={20} width={240} /> | ||
</span> | ||
</Box> | ||
</> | ||
); | ||
|
||
const skeletonList = []; | ||
for (let index = 0; index < skeletonCount; index++) { | ||
skeletonList.push(<div key={index}>{expandableItemSkeleton}</div>); | ||
} | ||
|
||
return ( | ||
<Card variant="outlined" sx={{ mb: 3 }}> | ||
<Box className={classes.testGroupCardHeader}> | ||
<Skeleton variant="circular" height={24} width={24} /> | ||
<span className={classes.testGroupCardHeaderText}> | ||
<Skeleton height={20} width={240} /> | ||
</span> | ||
<span className={classes.testGroupCardHeaderButton}> | ||
{windowIsSmall ? ( | ||
<Skeleton variant="circular" height={24} width={24} sx={{ mr: 1 }} /> | ||
) : ( | ||
<Skeleton variant="rounded" height={30} width={140} /> | ||
)} | ||
</span> | ||
</Box> | ||
<Divider /> | ||
<Box m={2.5}> | ||
<Skeleton height={10} sx={{ my: 2 }} /> | ||
<Skeleton height={10} width="90%" sx={{ my: 2 }} /> | ||
<Skeleton height={10} width="95%" sx={{ my: 2 }} /> | ||
<Skeleton height={10} sx={{ my: 2 }} /> | ||
<Skeleton height={10} width="90%" sx={{ my: 2 }} /> | ||
<Skeleton height={10} width="95%" sx={{ my: 2 }} /> | ||
<Skeleton height={10} width="50%" sx={{ my: 2 }} /> | ||
</Box> | ||
{skeletonList} | ||
</Card> | ||
); | ||
}; | ||
|
||
export default TestSessionSkeleton; |
72 changes: 72 additions & 0 deletions
72
client/src/components/Skeletons/__tests__/Skeletons.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import React from 'react'; | ||
import { MemoryRouter } from 'react-router-dom'; | ||
import { render } from '@testing-library/react'; | ||
import { SnackbarProvider } from 'notistack'; | ||
import ThemeProvider from 'components/ThemeProvider'; | ||
import AppSkeleton from 'components/Skeletons/AppSkeleton'; | ||
import DrawerSkeleton from 'components/Skeletons/DrawerSkeleton'; | ||
import FooterSkeleton from 'components/Skeletons/FooterSkeleton'; | ||
import HeaderSkeleton from 'components/Skeletons/HeaderSkeleton'; | ||
import TestSessionSkeleton from 'components/Skeletons/TestSessionSkeleton'; | ||
|
||
describe('Skeleton Components', () => { | ||
it('renders App Skeleton', () => { | ||
render( | ||
<MemoryRouter> | ||
<ThemeProvider> | ||
<SnackbarProvider> | ||
<AppSkeleton /> | ||
</SnackbarProvider> | ||
</ThemeProvider> | ||
</MemoryRouter> | ||
); | ||
}); | ||
|
||
it('renders Drawer Skeleton', () => { | ||
render( | ||
<MemoryRouter> | ||
<ThemeProvider> | ||
<SnackbarProvider> | ||
<DrawerSkeleton /> | ||
</SnackbarProvider> | ||
</ThemeProvider> | ||
</MemoryRouter> | ||
); | ||
}); | ||
|
||
it('renders Footer Skeleton', () => { | ||
render( | ||
<MemoryRouter> | ||
<ThemeProvider> | ||
<SnackbarProvider> | ||
<FooterSkeleton /> | ||
</SnackbarProvider> | ||
</ThemeProvider> | ||
</MemoryRouter> | ||
); | ||
}); | ||
|
||
it('renders Header Skeleton', () => { | ||
render( | ||
<MemoryRouter> | ||
<ThemeProvider> | ||
<SnackbarProvider> | ||
<HeaderSkeleton /> | ||
</SnackbarProvider> | ||
</ThemeProvider> | ||
</MemoryRouter> | ||
); | ||
}); | ||
|
||
it('renders TestSessionSkeleton Skeleton', () => { | ||
render( | ||
<MemoryRouter> | ||
<ThemeProvider> | ||
<SnackbarProvider> | ||
<TestSessionSkeleton /> | ||
</SnackbarProvider> | ||
</ThemeProvider> | ||
</MemoryRouter> | ||
); | ||
}); | ||
}); |
Oops, something went wrong.