Skip to content

Commit

Permalink
feat: add Capture counts to Grower Details dialog (Greenstand#222)
Browse files Browse the repository at this point in the history
* feat: add captures count list to grower details

* feat: finish the frontend for captures count in grower detail dialog

* feat: display the count of for each capture status in grower detail

* fix: call api to get related captures for each grower for counting status

* fix: get captures async for each grower

* fix: filter captures test

* fix: change the query to get captures count for each verification status
  • Loading branch information
tranquanghuy0801 authored and Ny-Rianala committed Feb 9, 2022
1 parent 8938ed3 commit d1b9288
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 5 deletions.
142 changes: 142 additions & 0 deletions src/components/GrowerDetail.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,18 @@ import CardMedia from '@material-ui/core/CardMedia';
import Grid from '@material-ui/core/Grid';
import IconButton from '@material-ui/core/IconButton';
import Box from '@material-ui/core/Box';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemText from '@material-ui/core/ListItemText';
import ListItemAvatar from '@material-ui/core/ListItemAvatar';
import Avatar from '@material-ui/core/Avatar';
import Drawer from '@material-ui/core/Drawer';
import Close from '@material-ui/icons/Close';
import Person from '@material-ui/icons/Person';
import Divider from '@material-ui/core/Divider';
import EditIcon from '@material-ui/icons/Edit';
import { LinearProgress } from '@material-ui/core';
import { Done, Clear, HourglassEmptyOutlined } from '@material-ui/icons';
import Fab from '@material-ui/core/Fab';
import api from '../api/growers';
import { getDateTimeStringLocale } from '../common/locale';
Expand All @@ -21,6 +28,8 @@ import OptimizedImage from './OptimizedImage';
import LinkToWebmap from './common/LinkToWebmap';
import { CopyButton } from './common/CopyButton';
import CopyNotification from './common/CopyNotification';
import FilterModel from '../models/Filter';
import treeTrackerApi from 'api/treeTrackerApi';

const GROWER_IMAGE_SIZE = 441;

Expand Down Expand Up @@ -56,6 +65,28 @@ const useStyle = makeStyles((theme) => ({
position: 'relative',
height: `${GROWER_IMAGE_SIZE}px`,
},
listCaptures: {
display: 'flex',
alignItems: 'center',
},
rejectedChip: {
backgroundColor: theme.palette.stats.red.replace(/[^,]+(?=\))/, '0.2'), // Change opacity of rgba
color: theme.palette.stats.red,
fontWeight: 700,
fontSize: '0.8em',
},
awaitingChip: {
backgroundColor: theme.palette.stats.orange.replace(/[^,]+(?=\))/, '0.2'), // Change opacity of rgba
color: theme.palette.stats.orange,
fontWeight: 700,
fontSize: '0.8em',
},
approvedChip: {
backgroundColor: theme.palette.stats.green.replace(/[^,]+(?=\))/, '0.2'), // Change opacity of rgba
color: theme.palette.stats.green,
fontWeight: 700,
fontSize: '0.8em',
},
}));

const GrowerDetail = (props) => {
Expand All @@ -70,6 +101,8 @@ const GrowerDetail = (props) => {
const [deviceIdentifiers, setDeviceIdentifiers] = useState([]);
const [snackbarOpen, setSnackbarOpen] = useState(false);
const [snackbarLabel, setSnackbarLabel] = useState('');
const [verificationStatus, setVerificationStatus] = useState({});
const [loading, setLoading] = useState(false);

useEffect(() => {
async function loadGrowerDetail() {
Expand Down Expand Up @@ -115,6 +148,39 @@ const GrowerDetail = (props) => {
// eslint-disable-next-line
}, [growerId, growerContext.growers]);

useEffect(() => {
async function loadCaptures() {
if (growerId) {
setLoading(true);
const [
approvedCount,
awaitingCount,
rejectedCount,
] = await Promise.all([
getCaptureCountGrower(true, true, growerId),
getCaptureCountGrower(true, false, growerId),
getCaptureCountGrower(false, false, growerId),
]);
setVerificationStatus({
approved: approvedCount,
awaiting: awaitingCount,
rejected: rejectedCount,
});
setLoading(false);
}
}
loadCaptures();
}, [growerId]);

async function getCaptureCountGrower(active, approved, growerId) {
let filter = new FilterModel();
filter.planterId = growerId;
filter.active = active;
filter.approved = approved;
const countResponse = await treeTrackerApi.getCaptureCount(filter);
return countResponse && countResponse.count ? countResponse.count : 0;
}

async function getGrower(payload) {
const { id } = payload;
let grower = growerContext.growers?.find((p) => p.id === id); // Look for a match in the context first
Expand Down Expand Up @@ -205,6 +271,82 @@ const GrowerDetail = (props) => {
</Typography>
</Grid>
<Divider />
<Grid container direction="column" className={classes.box}>
<Typography variant="subtitle1">Captures</Typography>
{loading ? (
<LinearProgress color="primary" />
) : (
<List className={classes.listCaptures}>
<Box
borderColor="grey.300"
borderRadius={10}
border={0.5}
m={0.5}
>
<ListItem>
<ListItemAvatar>
<Avatar className={classes.approvedChip}>
<Done />
</Avatar>
</ListItemAvatar>
<ListItemText
primary={
<Typography variant="h5">
{verificationStatus.approved || 0}
</Typography>
}
secondary="Approved"
/>
</ListItem>
</Box>
<Box
borderColor="grey.300"
borderRadius={10}
border={0.5}
m={0.5}
>
<ListItem>
<ListItemAvatar>
<Avatar className={classes.awaitingChip}>
<HourglassEmptyOutlined />
</Avatar>
</ListItemAvatar>
<ListItemText
primary={
<Typography variant="h5">
{verificationStatus.awaiting || 0}
</Typography>
}
secondary="Awaiting"
/>
</ListItem>
</Box>
<Box
borderColor="grey.300"
borderRadius={10}
border={0.5}
m={0.5}
>
<ListItem>
<ListItemAvatar>
<Avatar className={classes.rejectedChip}>
<Clear />
</Avatar>
</ListItemAvatar>
<ListItemText
primary={
<Typography variant="h5">
{verificationStatus.rejected || 0}
</Typography>
}
secondary="Rejected"
/>
</ListItem>
</Box>
</List>
)}
</Grid>
<Divider />
<Grid container direction="column" className={classes.box}>
<Typography variant="subtitle1">Email address</Typography>
<Typography variant="body1">{grower.email || '---'}</Typography>
Expand Down
2 changes: 1 addition & 1 deletion src/models/Filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export default class Filter {
where.active = this.active;
}

if (this.planterId !== undefined && this.planterId.length > 0) {
if (this.planterId !== undefined) {
where.planterId = this.planterId;
}

Expand Down
8 changes: 4 additions & 4 deletions src/models/Filter.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ describe('Filter, with initial values about this filter object', () => {
filter.dateEnd = '2019-07-30';
filter.approved = true;
filter.active = true;
filter.planterId = '1';
filter.planterId = 1;
filter.deviceIdentifier = '1';
filter.planterIdentifier = '1';
});
Expand Down Expand Up @@ -63,7 +63,7 @@ describe('Filter, with initial values about this filter object', () => {

it('getWhereObj() should match: planterId=1', () => {
expect(filter.getWhereObj()).toEqual(
expect.objectContaining({ planterId: '1' }),
expect.objectContaining({ planterId: 1 }),
);
});

Expand Down Expand Up @@ -91,10 +91,10 @@ describe('Filter, with initial values about this filter object', () => {
//}}}
});

describe('set planterId = ""', () => {
describe('set planterId = undefined', () => {
//{{{
beforeEach(() => {
filter.planterId = '';
filter.planterId = undefined;
});

it('loopback object should not match any [planterId]', () => {
Expand Down

0 comments on commit d1b9288

Please sign in to comment.