Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Surveys List Component #268

Merged
merged 9 commits into from
May 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions app/src/components/surveys/SurveysList.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { render } from '@testing-library/react';
import { IGetProjectSurvey } from 'interfaces/useProjectApi.interface';
import React from 'react';
import SurveysList from './SurveysList';

describe('SurveysList', () => {
it('renders correctly with surveys', () => {
const surveysList: IGetProjectSurvey[] = [
{
id: 1,
name: 'Moose Survey 1',
species: 'Moose',
start_date: '2021-04-09 11:53:53',
end_date: '2021-05-09 11:53:53',
status_name: 'Unpublished'
},
{
id: 2,
name: 'Moose Survey 2',
species: 'Moose',
start_date: '2021-04-09 11:53:53',
end_date: '2021-06-10 11:53:53',
status_name: 'Published'
}
];

const { getByText, queryByText } = render(<SurveysList surveysList={surveysList} />);

expect(queryByText('No Surveys')).toBeNull();
expect(getByText('Moose Survey 1')).toBeInTheDocument();
expect(getByText('Moose Survey 2')).toBeInTheDocument();
});

it('renders correctly with no surveys', () => {
const { getByText } = render(<SurveysList surveysList={[]} />);

expect(getByText('No Surveys')).toBeInTheDocument();
});
});
134 changes: 134 additions & 0 deletions app/src/components/surveys/SurveysList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import Chip from '@material-ui/core/Chip';
import Link from '@material-ui/core/Link';
import Paper from '@material-ui/core/Paper';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableContainer from '@material-ui/core/TableContainer';
import TableHead from '@material-ui/core/TableHead';
import TablePagination from '@material-ui/core/TablePagination';
import TableRow from '@material-ui/core/TableRow';
import makeStyles from '@material-ui/core/styles/makeStyles';
import { Theme } from '@material-ui/core/styles/createMuiTheme';
import { SurveyStatusType } from 'constants/misc';
import clsx from 'clsx';
import { IGetProjectSurvey } from 'interfaces/useProjectApi.interface';
import React, { useState } from 'react';
import { DATE_FORMAT } from 'constants/dateFormats';
import { getFormattedDateRangeString } from 'utils/Utils';

const useStyles = makeStyles((theme: Theme) => ({
table: {
minWidth: 650
},
heading: {
fontWeight: 'bold'
},
tableCellBorderTop: {
borderTop: '1px solid rgba(224, 224, 224, 1)'
},
chip: {
padding: '0px 8px',
borderRadius: '4px',
color: 'white'
},
chipUnpublished: {
backgroundColor: theme.palette.text.secondary
},
chipPublished: {
backgroundColor: theme.palette.success.light
}
}));

export interface ISurveysListProps {
surveysList: IGetProjectSurvey[];
}

const SurveysList: React.FC<ISurveysListProps> = (props) => {
const classes = useStyles();

const [rowsPerPage, setRowsPerPage] = useState(5);
const [page, setPage] = useState(0);

const handleChangePage = (event: unknown, newPage: number) => {
setPage(newPage);
};

const handleChangeRowsPerPage = (event: React.ChangeEvent<HTMLInputElement>) => {
setRowsPerPage(parseInt(event.target.value, 10));
setPage(0);
};

const getChipIcon = (status_name: string) => {
let chipLabel;
let chipStatusClass;

if (SurveyStatusType.UNPUBLISHED === status_name) {
chipLabel = 'UNPUBLISHED';
chipStatusClass = classes.chipUnpublished;
} else if (SurveyStatusType.PUBLISHED === status_name) {
chipLabel = 'PUBLISHED';
chipStatusClass = classes.chipPublished;
}

return <Chip className={clsx(classes.chip, chipStatusClass)} label={chipLabel} />;
};

return (
<Paper>
<TableContainer>
<Table className={classes.table} aria-label="surveys-list-table">
<TableHead>
<TableRow>
<TableCell className={classes.heading}>Name</TableCell>
<TableCell className={classes.heading}>Species</TableCell>
<TableCell className={classes.heading}>Timeline</TableCell>
<TableCell className={classes.heading}>Status</TableCell>
</TableRow>
</TableHead>
<TableBody>
{props.surveysList.length > 0 &&
props.surveysList.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map((row, index) => (
<TableRow key={row.id}>
<TableCell component="th" scope="row">
<Link
underline="always"
component="button"
variant="body2"
onClick={() => console.log('survey clicked')}>
{row.name}
</Link>
</TableCell>
<TableCell>{row.species}</TableCell>
<TableCell>
{getFormattedDateRangeString(DATE_FORMAT.ShortMediumDateFormat2, row.start_date, row.end_date)}
</TableCell>
<TableCell>{getChipIcon(row.status_name)}</TableCell>
</TableRow>
))}
{!props.surveysList.length && (
<TableRow>
<TableCell colSpan={4} align="center">
No Surveys
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</TableContainer>
{props.surveysList.length > 0 && (
<TablePagination
rowsPerPageOptions={[5, 10, 15, 20]}
component="div"
count={props.surveysList.length}
rowsPerPage={rowsPerPage}
page={page}
onChangePage={handleChangePage}
onChangeRowsPerPage={handleChangeRowsPerPage}
/>
)}
</Paper>
);
};

export default SurveysList;
1 change: 1 addition & 0 deletions app/src/constants/dateFormats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export enum DATE_FORMAT {
ShortDateFormatMonthFirst = 'MM/DD/YYYY', //01/05/2020
ShortDateTimeFormat = 'YYYY-MM-DD, h:mm a', //2020-01-05, 3:30 pm
ShortMediumDateFormat = 'MMM D, YYYY', //Jan 5, 2020
ShortMediumDateFormat2 = 'MMMM DD, YYYY', //Jan 05, 2020
ShortMediumDateTimeFormat = 'MMM D, YYYY, h:mm a', //Jan 5, 2020, 3:30 pm
MediumDateFormat = 'MMMM D, YYYY', //January 5, 2020
MediumDateFormat2 = 'MMMM-DD-YYYY', //January-5-2020
Expand Down
5 changes: 5 additions & 0 deletions app/src/constants/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@ export enum AdministrativeActivityStatusType {
ACTIONED = 'Actioned',
REJECTED = 'Rejected'
}

export enum SurveyStatusType {
UNPUBLISHED = 'Unpublished',
PUBLISHED = 'Published'
}
2 changes: 1 addition & 1 deletion app/src/features/projects/view/ProjectPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ const ProjectPage: React.FC = () => {
{location.pathname.includes('/details') && (
<ProjectDetails projectForViewData={projectWithDetails} codes={codes} refresh={getProject} />
)}
{location.pathname.includes('/surveys') && <ProjectSurveys projectForViewData={projectWithDetails} />}
{location.pathname.includes('/surveys') && <ProjectSurveys />}
{location.pathname.includes('/attachments') && (
<ProjectAttachments projectForViewData={projectWithDetails} />
)}
Expand Down
14 changes: 4 additions & 10 deletions app/src/features/projects/view/ProjectSurveys.test.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
import { render } from '@testing-library/react';
import { createMemoryHistory } from 'history';
import React from 'react';
import { Router } from 'react-router';
import ProjectSurveys from './ProjectSurveys';

const history = createMemoryHistory();

describe('ProjectSurveys', () => {
it('renders correctly', () => {
const { asFragment } = render(
<Router history={history}>
<ProjectSurveys projectData={{}} />
</Router>
);
const { getByText } = render(<ProjectSurveys />);

expect(asFragment()).toMatchSnapshot();
expect(getByText('Surveys')).toBeInTheDocument();
expect(getByText('Add Survey')).toBeInTheDocument();
expect(getByText('Moose Survey 1')).toBeInTheDocument();
});
});
41 changes: 25 additions & 16 deletions app/src/features/projects/view/ProjectSurveys.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,42 @@
import Box from '@material-ui/core/Box';
import Paper from '@material-ui/core/Paper';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import { IGetProjectForViewResponse } from 'interfaces/useProjectApi.interface';
import SurveysList from 'components/surveys/SurveysList';
import { IGetProjectSurvey } from 'interfaces/useProjectApi.interface';
import React from 'react';

export interface IProjectSurveysProps {
projectForViewData: IGetProjectForViewResponse;
}

/**
* Project surveys content for a project.
*
* @return {*}
*/
const ProjectSurveys: React.FC<IProjectSurveysProps> = () => {
const ProjectSurveys = () => {
// TODO: Replace this with the result of an API call giving us back the surveyList data
const surveysList: IGetProjectSurvey[] = [
{
id: 1,
name: 'Moose Survey 1',
species: 'Moose',
start_date: '2021-04-09 11:53:53',
end_date: '2021-05-09 11:53:53',
status_name: 'Unpublished'
}
];

return (
<>
<Box mb={5}>
<Typography variant="h2">Project Surveys</Typography>
</Box>
<Box mb={3}>
<Paper>
<Box p={3}>Project survey component 1 placeholder</Box>
</Paper>
<Box display="flex" justifyContent="space-between">
<Box>
<Typography variant="h2">Surveys</Typography>
</Box>
<Button variant="outlined" color="primary" onClick={() => console.log('add survey clicked')}>
Add Survey
</Button>
</Box>
</Box>
<Box mb={3}>
<Paper>
<Box p={3}>Project survey component 2 placeholder</Box>
</Paper>
<SurveysList surveysList={surveysList} />
</Box>
</>
);
Expand Down

This file was deleted.

9 changes: 9 additions & 0 deletions app/src/interfaces/useProjectApi.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ import { IProjectPermitForm } from 'features/projects/components/ProjectPermitFo
import { IProjectSpeciesForm } from 'features/projects/components/ProjectSpeciesForm';
import { Feature } from 'geojson';

export interface IGetProjectSurvey {
id: number;
name: string;
species: string;
start_date: string;
end_date: string;
status_name: string;
}

export interface IGetProjectAttachment {
id: number;
fileName: string;
Expand Down