From d1b928882ec18afe54824c60e8729f4d22497397 Mon Sep 17 00:00:00 2001 From: "Huy Tran (Harry)" Date: Mon, 13 Dec 2021 07:02:34 +1000 Subject: [PATCH] feat: add Capture counts to Grower Details dialog (#222) * 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 --- src/components/GrowerDetail.js | 142 +++++++++++++++++++++++++++++++++ src/models/Filter.js | 2 +- src/models/Filter.test.js | 8 +- 3 files changed, 147 insertions(+), 5 deletions(-) diff --git a/src/components/GrowerDetail.js b/src/components/GrowerDetail.js index d0a8b46a4..7d33023f7 100644 --- a/src/components/GrowerDetail.js +++ b/src/components/GrowerDetail.js @@ -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'; @@ -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; @@ -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) => { @@ -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() { @@ -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 @@ -205,6 +271,82 @@ const GrowerDetail = (props) => { + + Captures + {loading ? ( + + ) : ( + + + + + + + + + + {verificationStatus.approved || 0} + + } + secondary="Approved" + /> + + + + + + + + + + + {verificationStatus.awaiting || 0} + + } + secondary="Awaiting" + /> + + + + + + + + + + + {verificationStatus.rejected || 0} + + } + secondary="Rejected" + /> + + + + )} + + Email address {grower.email || '---'} diff --git a/src/models/Filter.js b/src/models/Filter.js index 5408a696f..b6657b7bc 100644 --- a/src/models/Filter.js +++ b/src/models/Filter.js @@ -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; } diff --git a/src/models/Filter.test.js b/src/models/Filter.test.js index 8ffa02887..5a9ea121c 100644 --- a/src/models/Filter.test.js +++ b/src/models/Filter.test.js @@ -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'; }); @@ -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 }), ); }); @@ -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]', () => {