Skip to content

Commit

Permalink
FI-2454: Add landing page and suite options skeletons (#453)
Browse files Browse the repository at this point in the history
* add landing page and selection skeletons

* add suite options skeleton

* remove testing null input

* add skeleton render tests

* Update client/src/components/App/Router.tsx

Co-authored-by: Dylan Hall <dehall@mitre.org>

* resolve lint error

---------

Co-authored-by: Alyssa Wang <awang@mitre.org>
Co-authored-by: Dylan Hall <dehall@mitre.org>
  • Loading branch information
3 people authored Feb 19, 2024
1 parent 4dbcdeb commit 022aeaf
Show file tree
Hide file tree
Showing 13 changed files with 291 additions and 32 deletions.
4 changes: 0 additions & 4 deletions client/src/components/App/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,6 @@ const App: FC<unknown> = () => {
}
};

if (!testSuites || testSuites.length === 0) {
return <></>;
}

return (
<SnackbarProvider
dense
Expand Down
11 changes: 7 additions & 4 deletions client/src/components/App/Router.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,34 @@
import React from 'react';
import { createBrowserRouter } from 'react-router-dom';
import Page from '~/components/App/Page';
import LandingPage from '~/components/LandingPage';
import SuiteOptionsPage from '~/components/SuiteOptionsPage';
import TestSessionWrapper from '~/components/TestSuite/TestSessionWrapper';
import LandingPageSkeleton from '~/components/Skeletons/LandingPageSkeleton';
import SuiteOptionsPageSkeleton from '~/components/Skeletons/SuiteOptionsPageSkeleton';
import { basePath } from '~/api/infernoApiService';
import Page from '~/components/App/Page';
import { TestSuite } from '~/models/testSuiteModels';

export const router = (testSuites: TestSuite[]) => {
const testSuitesExist = !!testSuites && testSuites.length > 0;
return createBrowserRouter(
[
{
path: '/',
element: (
<Page title={`Inferno Test Suites`}>
<LandingPage testSuites={testSuites} />
{testSuitesExist ? <LandingPage testSuites={testSuites} /> : <LandingPageSkeleton />}
</Page>
),
},
{
path: ':test_suite_id',
element: <Page title="Options" />,
loader: ({ params }) => {
if (testSuites.length === 0) return <></>;
if (!testSuitesExist) return <SuiteOptionsPageSkeleton />;
const suiteId: string = params.test_suite_id || '';
const suite = testSuites.find((suite) => suite.id === suiteId);
return <SuiteOptionsPage testSuite={suite} />;
return suite ? <SuiteOptionsPage testSuite={suite} /> : <SuiteOptionsPageSkeleton />;
},
},
{
Expand Down
30 changes: 19 additions & 11 deletions client/src/components/LandingPage/LandingPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import infernoLogo from '~/images/inferno_logo.png';
import SelectionPanel from '~/components/_common/SelectionPanel/SelectionPanel';
import lightTheme from '~/styles/theme';
import useStyles from './styles';
import SelectionSkeleton from '../Skeletons/SelectionSkeletion';

export interface LandingPageProps {
testSuites: TestSuite[] | undefined;
Expand Down Expand Up @@ -128,17 +129,24 @@ const LandingPage: FC<LandingPageProps> = ({ testSuites }) => {
py={4}
sx={{ backgroundColor: lightTheme.palette.common.grayLightest }}
>
<SelectionPanel
title="Test Suites"
options={(testSuites || []).sort((testSuite1: TestSuite, testSuite2: TestSuite): number =>
testSuite1.title.localeCompare(testSuite2.title)
)}
setSelection={setSelected}
submitAction={() =>
startTestingClick(testSuites?.find((suite: TestSuite) => suite.id === testSuiteChosen))
}
submitText="Select Suite"
/>
{testSuites ? (
<SelectionPanel
title="Test Suites"
options={(testSuites || []).sort(
(testSuite1: TestSuite, testSuite2: TestSuite): number =>
testSuite1.title.localeCompare(testSuite2.title)
)}
setSelection={setSelected}
submitAction={() =>
startTestingClick(
testSuites?.find((suite: TestSuite) => suite.id === testSuiteChosen)
)
}
submitText="Select Suite"
/>
) : (
<SelectionSkeleton />
)}
</Box>
</Container>
);
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/Skeletons/AppSkeleton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const AppSkeleton: FC<Record<string, never>> = () => {
const windowIsSmall = useAppStore((state) => state.windowIsSmall);

return (
<Box className={classes.testSuiteMain}>
<Box className={classes.testSuiteMain} data-testid="appSkeleton">
<DrawerSkeleton />
<main
style={{
Expand Down
7 changes: 6 additions & 1 deletion client/src/components/Skeletons/DrawerSkeleton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ const DrawerSkeleton: FC<Record<string, never>> = () => {
return windowIsSmall ? (
<></>
) : (
<Drawer variant="permanent" anchor="left" classes={{ paper: drawerClasses.drawerPaper }}>
<Drawer
variant="permanent"
anchor="left"
classes={{ paper: drawerClasses.drawerPaper }}
data-testid="drawerSkeleton"
>
<Skeleton variant="rounded" height={32} sx={{ m: 2 }} />
<Divider />
<Box className={treeClasses.testSuiteTreePanel} py={1}>
Expand Down
1 change: 1 addition & 0 deletions client/src/components/Skeletons/FooterSkeleton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const FooterSkeleton: FC<Record<string, never>> = () => {
maxHeight: `${footerHeight}px`,
backgroundColor: 'white',
}}
data-testid="footerSkeleton"
>
<Box display="flex" flexDirection="row" justifyContent="space-between" width="100%">
<Box display="flex" alignItems="center" px={2}>
Expand Down
1 change: 1 addition & 0 deletions client/src/components/Skeletons/HeaderSkeleton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const HeaderSkeleton: FC<Record<string, never>> = () => {
minHeight: `${headerHeight}px`, // For responsive screens
maxHeight: `${headerHeight}px`, // For responsive screens
}}
data-testid="headerSkeleton"
>
<Toolbar className={classes.toolbar}>
{/* Home button */}
Expand Down
65 changes: 65 additions & 0 deletions client/src/components/Skeletons/LandingPageSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import React, { FC } from 'react';
import { Box, Container, Skeleton } from '@mui/material';
import { useAppStore } from '~/store/app';
import SelectionSkeleton from '~/components/Skeletons/SelectionSkeletion';
import useStyles from '~/components/LandingPage/styles';
import lightTheme from '~/styles/theme';

const LandingPageSkeleton: FC<Record<string, never>> = () => {
const { classes } = useStyles();
const windowIsSmall = useAppStore((state) => state.windowIsSmall);

return (
<Container className={classes.main} data-testid="landingPageSkeleton">
<Box
display="flex"
flexDirection="column"
justifyContent={windowIsSmall ? 'center' : 'flex-end'}
alignItems="center"
px={2}
>
<Box
display="flex"
flexDirection="column"
my={2}
alignItems="center"
justifyContent="center"
>
<Skeleton variant="rounded" height={70} width={250} style={{ margin: '32px' }} />
<Skeleton
variant="rounded"
height={40}
width={windowIsSmall ? 200 : 400}
style={{ margin: '8px' }}
/>
</Box>
<Box mb={2} alignItems="center">
<Skeleton
variant="rounded"
height={20}
width={windowIsSmall ? 250 : 500}
style={{ margin: '8px' }}
/>
<Skeleton
variant="rounded"
height={20}
width={windowIsSmall ? 250 : 500}
style={{ margin: '8px' }}
/>
</Box>
</Box>
<Box
display="flex"
flexDirection="column"
alignItems="center"
width="100%"
py={4}
sx={{ backgroundColor: lightTheme.palette.common.grayLightest }}
>
<SelectionSkeleton />
</Box>
</Container>
);
};

export default LandingPageSkeleton;
48 changes: 48 additions & 0 deletions client/src/components/Skeletons/SelectionSkeletion.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React, { FC } from 'react';
import { Box, Paper, Skeleton } from '@mui/material';
import { useAppStore } from '~/store/app';
import useStyles from '~/components/_common/SelectionPanel/styles';

const SelectionSkeleton: FC<Record<string, never>> = () => {
const { classes } = useStyles();
const windowIsSmall = useAppStore((state) => state.windowIsSmall);
const optionCount = 3;

const optionSkeleton = (
<Skeleton
variant="rounded"
height={10}
width={windowIsSmall ? 200 : 300}
style={{ margin: '32px' }}
/>
);

const skeletonList = [];
for (let index = 0; index < optionCount; index++) {
skeletonList.push(<div key={index}>{optionSkeleton}</div>);
}

return (
<Box display="flex" data-testid="selectionSkeleton">
<Paper
elevation={0}
className={classes.optionsList}
sx={{ width: windowIsSmall ? 'auto' : '400px', maxWidth: '400px' }}
>
<Box display="flex" alignItems="center" justifyContent={'center'} mx={1}>
<Skeleton variant="rounded" height={30} width={150} style={{ marginTop: '16px' }} />
</Box>

<Box px={2} pb={2}>
{skeletonList}
</Box>

<Box px={2}>
<Skeleton variant="rounded" height={40} />
</Box>
</Paper>
</Box>
);
};

export default SelectionSkeleton;
64 changes: 64 additions & 0 deletions client/src/components/Skeletons/SuiteOptionsPageSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React, { FC } from 'react';
import { Box, Container, Skeleton } from '@mui/material';
import { useAppStore } from '~/store/app';
import SelectionSkeleton from '~/components/Skeletons/SelectionSkeletion';
import useStyles from '~/components/SuiteOptionsPage/styles';
import lightTheme from '~/styles/theme';

const SuiteOptionsPageSkeleton: FC<Record<string, never>> = () => {
const { classes } = useStyles();
const windowIsSmall = useAppStore((state) => state.windowIsSmall);
const textLineCount = 10;

const textLineSkeleton = (
<Skeleton
variant="rounded"
height={10}
width={windowIsSmall ? 300 : 400}
style={{ margin: '8px' }}
/>
);

const skeletonList = [];
for (let index = 0; index < textLineCount; index++) {
skeletonList.push(<div key={index}>{textLineSkeleton}</div>);
}

return (
<Container
className={classes.main}
sx={{ flexDirection: windowIsSmall ? '' : 'column' }}
data-testid="suiteOptionsPageSkeleton"
>
<Box
display="flex"
flexDirection="column"
justifyContent="center"
alignItems="center"
px={windowIsSmall ? 0 : 8}
my={3}
>
<Box display="flex" alignItems="center" m={4}>
<Skeleton variant="rounded" height={40} width={windowIsSmall ? 200 : 350} />
</Box>
<Box display="flex" flexDirection="column" justifyContent="center" px={2} mb={3}>
{skeletonList}
</Box>
</Box>
<Box
display="flex"
height={windowIsSmall ? 'none' : '100%'}
width={windowIsSmall ? '100%' : 'none'}
justifyContent="center"
alignItems="center"
sx={{ backgroundColor: lightTheme.palette.common.grayLightest }}
>
<Box display="flex" justifyContent="center" m={3}>
<SelectionSkeleton />
</Box>
</Box>
</Container>
);
};

export default SuiteOptionsPageSkeleton;
2 changes: 1 addition & 1 deletion client/src/components/Skeletons/TestSessionSkeleton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const TestSessionSkeleton: FC<Record<string, never>> = () => {
}

return (
<Card variant="outlined" sx={{ mb: 3 }}>
<Card variant="outlined" sx={{ mb: 3 }} data-testid="testSessionSkeleton">
<Box className={classes.testGroupCardHeader}>
<Skeleton variant="circular" height={24} width={24} />
<span className={classes.testGroupCardHeaderText}>
Expand Down
Loading

0 comments on commit 022aeaf

Please sign in to comment.