Skip to content

Commit

Permalink
Merge pull request #183 from cisagov/rsc-filter-resources
Browse files Browse the repository at this point in the history
Filter Resources on RSC Dashboard Details Page
  • Loading branch information
schmelz21 authored Apr 24, 2024
2 parents 5152c05 + d2fb7ea commit 3278b1d
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 44 deletions.
119 changes: 75 additions & 44 deletions frontend/src/components/ReadySetCyber/RSCQuestion.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
import Button from '@mui/material/Button';
import { Box, Button, Grid, Typography, Radio } from '@mui/material';
import { isResourceVisible } from './helpers/index';
import { IconFilter } from './components/index';

interface Props {
categories: Category[];
Expand Down Expand Up @@ -31,6 +31,10 @@ interface Resource {
type: string;
url: string;
}
// Concatenates the last one or two characters of a string
const questionNumber = (n: string) => {
return n.charAt(n.length - 2) === '0' ? n.slice(-1) : n.slice(-2);
};

export const RSCQuestion: React.FC<Props> = ({ categories }) => {
return (
Expand All @@ -57,7 +61,7 @@ export const RSCQuestion: React.FC<Props> = ({ categories }) => {
}}
>
<Typography variant="h6" gutterBottom>
Question {entry.question.number}
Question {questionNumber(entry.question.number)}
</Typography>
<Typography variant="subtitle1" gutterBottom>
{entry.question.longForm}
Expand All @@ -68,50 +72,77 @@ export const RSCQuestion: React.FC<Props> = ({ categories }) => {
</Typography>
)}
<Typography variant="subtitle2" gutterBottom>
Response: {entry.selection}
</Typography>
{entry.question.resources.length > 0 && (
<Box
Response:
<Grid
container
sx={{
bgcolor: 'white',
borderRadius: 1,
padding: 2,
marginTop: 1
alignItems: 'center',
backgroundColor: 'white',
width: 'fit-content',
border: '2px solid #ccc',
borderRadius: 0
}}
>
<Typography variant="h6" gutterBottom>
Recommended Resources
</Typography>
{entry.question.resources.map((resource, resIndex) => (
<Box
key={resIndex}
sx={{
borderBottom: '1px solid #ccc',
paddingBottom: 1,
marginBottom: 1
}}
>
<Typography variant="subtitle1">
{resource.type}
</Typography>
<Typography variant="subtitle2">
{resource.name}
</Typography>
<Typography variant="body2">
{resource.description}
</Typography>
<Button
variant="outlined"
color="primary"
href={resource.url}
target="_blank"
<Grid item marginLeft={'-0.25em'}>
<Radio checked={true} disabled={true} />
</Grid>
<Grid item paddingRight={'0.5em'}>
{entry.selection}
</Grid>
</Grid>
</Typography>
{entry.question.resources.length > 0 &&
isResourceVisible(entry.selection) && (
<Box
sx={{
bgcolor: 'white',
borderRadius: 1,
padding: 2,
marginTop: 1
}}
>
<Typography variant="h6" gutterBottom>
Recommended Resources
</Typography>
{entry.question.resources.map((resource, resIndex) => (
<Box
key={resIndex}
sx={{
borderBottom: '1px solid #ccc',
paddingBottom: 1,
marginBottom: 1
}}
>
Visit Resource
</Button>
</Box>
))}
</Box>
)}
<Grid container alignItems={'center'}>
<Grid item paddingRight={'0.25em'}>
<IconFilter type={resource.type} />
</Grid>

<Grid item>
<Typography variant="subtitle1">
{resource.type.charAt(0).toUpperCase() +
resource.type.slice(1)}
</Typography>
</Grid>
</Grid>
<Typography variant="subtitle2">
{resource.name}
</Typography>
<Typography variant="body2">
{resource.description}
</Typography>
<Button
variant="outlined"
color="primary"
href={resource.url}
target="_blank"
>
Visit Resource
</Button>
</Box>
))}
</Box>
)}
</Box>
))}
</Box>
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/components/ReadySetCyber/components/IconType.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import { getIconType } from '../helpers/index';

// Filter the resource type and return the corresponding icon
export const IconFilter = ({ type }: { type: string }) => {
const IconType = getIconType(type);
return (
<>
<IconType />
</>
);
};
1 change: 1 addition & 0 deletions frontend/src/components/ReadySetCyber/components/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './IconType';
31 changes: 31 additions & 0 deletions frontend/src/components/ReadySetCyber/helpers/filterResources.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';
import {
VideoLibrary,
Article,
LibraryBooks,
Handyman,
NotificationsActive
} from '@mui/icons-material';

interface ResourceTypes {
[key: string]: React.ElementType;
}

const resourcetypes: ResourceTypes = {
video: VideoLibrary,
article: Article,
tool: Handyman,
alerts: NotificationsActive
};

// Filter resource visibility by response
export const isResourceVisible = (response: string) => {
const r = response.toLowerCase();
return r === 'no' || r === 'not in scope' || r === 'not started';
};

// Filter the resource type and return the corresponding icon
export const getIconType = (type: string) => {
const ResourceIcon = resourcetypes[type];
return ResourceIcon ? ResourceIcon : LibraryBooks;
};
1 change: 1 addition & 0 deletions frontend/src/components/ReadySetCyber/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './filterResources';

0 comments on commit 3278b1d

Please sign in to comment.