-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Reef check surveys in Site page (#1064)
* Hide previous data while loading * Add reef check surveys in Sites survey list * Add default value to surveyList * Add tests * Add react-scan for performance profiling (#1065) * Use available width for timeline items * Format impact count and show all rows * Fix timeline styling issue * Scroll to top on route change * Update tests * Update index.tsx * Filter out empty rows * Fix hasSpotter when there is topTemp only (#1068) * Update index.tsx * Update index.tsx * [Snyk] Fix for 3 vulnerabilities (#1067) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-TAR-6476909 - https://snyk.io/vuln/SNYK-JS-INFLIGHT-6095116 - https://snyk.io/vuln/SNYK-JS-AXIOS-6671926 Co-authored-by: snyk-bot <snyk-bot@snyk.io> * Filter out empty rows for Fish and Invertebrates * Fix timeline skeleton * Show invertebrates header inline --------- Co-authored-by: ericboucher <eric.p.boucher@gmail.com> Co-authored-by: snyk-bot <snyk-bot@snyk.io>
- Loading branch information
1 parent
9ada832
commit bd00680
Showing
18 changed files
with
423 additions
and
44 deletions.
There are no files selected for viewing
70 changes: 70 additions & 0 deletions
70
packages/website/src/common/SiteDetails/Surveys/ReefCheckSurveyCard/index.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,70 @@ | ||
import React from 'react'; | ||
import { render } from '@testing-library/react'; | ||
import { mockReefCheckSurvey } from 'mocks/mockReefCheckSurvey'; | ||
import { ReefCheckSurvey } from 'store/ReefCheckSurveys'; | ||
import { BrowserRouter } from 'react-router-dom'; | ||
import { ReefCheckSurveyCard } from '.'; | ||
|
||
describe('ReefCheckSurveyCard', () => { | ||
function renderReefCheckSurveyCard(overrides: Partial<ReefCheckSurvey> = {}) { | ||
return render( | ||
<BrowserRouter> | ||
<ReefCheckSurveyCard | ||
survey={{ ...mockReefCheckSurvey, ...overrides }} | ||
/> | ||
, | ||
</BrowserRouter>, | ||
); | ||
} | ||
|
||
it('should render date', () => { | ||
const { getByText } = renderReefCheckSurveyCard(); | ||
|
||
expect( | ||
getByText(`Date: ${new Date(mockReefCheckSurvey.date).toLocaleString()}`), | ||
).toBeInTheDocument(); | ||
}); | ||
|
||
it('should render user if submittedBy is present', () => { | ||
const { getByText } = renderReefCheckSurveyCard({ | ||
submittedBy: 'Test User', | ||
}); | ||
expect(getByText('User: Test User')).toBeInTheDocument(); | ||
}); | ||
|
||
it('should render table with correct number of rows', () => { | ||
const { container } = renderReefCheckSurveyCard(); | ||
|
||
expect(container.querySelectorAll('mock-tablerow').length).toBe(3); | ||
}); | ||
|
||
it('should show correct counts in headers', () => { | ||
const { container } = renderReefCheckSurveyCard(); | ||
const headers = [ | ||
...container.querySelectorAll('mock-tablehead mock-tablecell').values(), | ||
].map((el) => el.textContent); | ||
expect(headers).toEqual( | ||
expect.arrayContaining([ | ||
'FISH (2)', | ||
'Count', | ||
'INVERTEBRATES (2)', | ||
'Count', | ||
'BLEACHING AND CORAL DIDEASES', | ||
'YES/NO', | ||
'IMPACT', | ||
'YES/NO', | ||
]), | ||
); | ||
}); | ||
|
||
it('should display link to survey details', () => { | ||
const { getByRole } = renderReefCheckSurveyCard(); | ||
|
||
expect( | ||
getByRole( | ||
(role, element) => | ||
role === 'link' && element?.textContent === 'VIEW DETAILS', | ||
), | ||
).toHaveAttribute('href', `/reef_check_survey/${mockReefCheckSurvey.id}`); | ||
}); | ||
}); |
162 changes: 162 additions & 0 deletions
162
packages/website/src/common/SiteDetails/Surveys/ReefCheckSurveyCard/index.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,162 @@ | ||
import React from 'react'; | ||
import { | ||
Box, | ||
Button, | ||
createStyles, | ||
Paper, | ||
Table, | ||
TableBody, | ||
TableCell, | ||
TableContainer, | ||
TableHead, | ||
TableRow, | ||
Theme, | ||
Typography, | ||
WithStyles, | ||
withStyles, | ||
} from '@material-ui/core'; | ||
import { groupBy, times } from 'lodash'; | ||
import { Link } from 'react-router-dom'; | ||
import cls from 'classnames'; | ||
import { reefCheckImpactRows, ReefCheckSurvey } from 'store/ReefCheckSurveys'; | ||
|
||
type ReefCheckSurveyCardIncomingProps = { | ||
survey: ReefCheckSurvey; | ||
}; | ||
|
||
const ReefCheckSurveyCardComponent = ({ | ||
survey, | ||
classes, | ||
}: ReefCheckSurveyCardProps) => { | ||
const stats = groupBy( | ||
// eslint-disable-next-line fp/no-mutating-methods | ||
survey.organisms | ||
.map((organism) => ({ | ||
...organism, | ||
count: organism.s1 + organism.s2 + organism.s3 + organism.s4, | ||
})) | ||
.filter( | ||
({ count, type }) => | ||
// Filter out fish and invertebrates with no count | ||
count > 0 || type === 'Impact' || type === 'Bleaching', | ||
) | ||
.sort((a, b) => b.count - a.count), | ||
({ type, organism }) => { | ||
if (type === 'Impact') { | ||
return reefCheckImpactRows.includes(organism) ? 'Impact' : 'Bleaching'; | ||
} | ||
return type; | ||
}, | ||
); | ||
|
||
const rowCount = Math.max( | ||
stats.Fish?.length ?? 0, | ||
stats.Invertebrate?.length ?? 0, | ||
stats.Bleaching?.length ?? 0, | ||
stats.Impact?.length ?? 0, | ||
); | ||
|
||
return ( | ||
<Paper className={classes.paper}> | ||
<Box display="flex" justifyContent="space-between"> | ||
<Typography>Date: {new Date(survey.date).toLocaleString()}</Typography> | ||
{survey.submittedBy && ( | ||
<Typography>User: {survey.submittedBy}</Typography> | ||
)} | ||
</Box> | ||
<TableContainer className={classes.tableRoot}> | ||
<Table size="small"> | ||
<TableHead> | ||
<TableRow className={classes.header}> | ||
<TableCell className={classes.label}> | ||
FISH ({stats.Fish?.length ?? 0}) | ||
</TableCell> | ||
<TableCell>Count</TableCell> | ||
<TableCell className={cls(classes.label, classes.noWrap)}> | ||
INVERTEBRATES ({stats.Invertebrate?.length ?? 0}) | ||
</TableCell> | ||
<TableCell>Count</TableCell> | ||
<TableCell className={classes.label}> | ||
BLEACHING AND CORAL DIDEASES | ||
</TableCell> | ||
<TableCell>YES/NO</TableCell> | ||
<TableCell className={classes.label}>IMPACT</TableCell> | ||
<TableCell>YES/NO</TableCell> | ||
</TableRow> | ||
</TableHead> | ||
<TableBody> | ||
{times(rowCount).map((i) => ( | ||
<TableRow key={i}> | ||
<TableCell className={classes.label}> | ||
{stats.Fish?.[i]?.organism} | ||
</TableCell> | ||
<TableCell>{stats.Fish?.[i]?.count}</TableCell> | ||
<TableCell className={classes.label}> | ||
{stats.Invertebrate?.[i]?.organism} | ||
</TableCell> | ||
<TableCell>{stats.Invertebrate?.[i]?.count}</TableCell> | ||
<TableCell className={classes.label}> | ||
{stats.Bleaching?.[i]?.organism} | ||
</TableCell> | ||
<TableCell> | ||
{formatImpactCount(stats.Bleaching?.[i]?.count)} | ||
</TableCell> | ||
<TableCell className={classes.label}> | ||
{stats.Impact?.[i]?.organism} | ||
</TableCell> | ||
<TableCell> | ||
{formatImpactCount(stats.Impact?.[i]?.count)} | ||
</TableCell> | ||
</TableRow> | ||
))} | ||
</TableBody> | ||
</Table> | ||
</TableContainer> | ||
|
||
<Box marginTop={2}> | ||
<Link to={`reef_check_survey/${survey.id}`}> | ||
<Button size="small" variant="outlined" color="primary"> | ||
VIEW DETAILS | ||
</Button> | ||
</Link> | ||
</Box> | ||
</Paper> | ||
); | ||
}; | ||
|
||
const formatImpactCount = (count?: number) => { | ||
if (count === undefined) { | ||
return ''; | ||
} | ||
return count > 0 ? 'YES' : 'NO'; | ||
}; | ||
|
||
const styles = (theme: Theme) => | ||
createStyles({ | ||
paper: { | ||
padding: 16, | ||
color: theme.palette.text.secondary, | ||
maxWidth: '100%', | ||
}, | ||
label: { | ||
backgroundColor: '#FAFAFA', | ||
}, | ||
tableRoot: { | ||
maxHeight: 200, | ||
}, | ||
header: { | ||
'& th': { | ||
borderBottom: '1px solid black', | ||
}, | ||
}, | ||
noWrap: { | ||
whiteSpace: 'nowrap', | ||
}, | ||
}); | ||
|
||
type ReefCheckSurveyCardProps = ReefCheckSurveyCardIncomingProps & | ||
WithStyles<typeof styles>; | ||
|
||
export const ReefCheckSurveyCard = withStyles(styles)( | ||
ReefCheckSurveyCardComponent, | ||
); |
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
Oops, something went wrong.