From 8fda2c031ae4ba3f94ceaeb095a0f50e4078fd49 Mon Sep 17 00:00:00 2001 From: Gwynn Dandridge-Perry Date: Thu, 13 Oct 2022 10:01:00 -0700 Subject: [PATCH] fix: bug for approving and rejecting a raw-capture in verify (#890) --- .env.development | 1 + src/api/apiUtils.js | 5 +-- src/api/treeTrackerApi.js | 63 +++++++++++++++++++----------- src/components/Verify.js | 12 ++++-- src/context/SpeciesContext.js | 2 +- src/context/VerifyContext.js | 72 +++++++++++++++++------------------ 6 files changed, 87 insertions(+), 68 deletions(-) diff --git a/.env.development b/.env.development index 48f24d106..a0a7adb77 100644 --- a/.env.development +++ b/.env.development @@ -1,6 +1,7 @@ REACT_APP_WEBMAP_DOMAIN=http://dev.treetracker.org REACT_APP_API_ROOT=https://dev-k8s.treetracker.org/api/admin REACT_APP_EARNINGS_ROOT=https://dev-k8s.treetracker.org/earnings +REACT_APP_FIELD_DATA_ROOT=https://dev-k8s.treetracker.org/field-data REACT_APP_GROWER_QUERY_API_ROOT=https://dev-k8s.treetracker.org/grower-account-query REACT_APP_IMAGES_API_ROOT=https://dev-k8s.treetracker.org/images REACT_APP_MESSAGING_ROOT=https://dev-k8s.treetracker.org/messaging diff --git a/src/api/apiUtils.js b/src/api/apiUtils.js index a2cf7a26a..d5c5dca95 100644 --- a/src/api/apiUtils.js +++ b/src/api/apiUtils.js @@ -4,14 +4,13 @@ const log = require('loglevel'); export async function handleResponse(response) { if (response.status === 204) return {}; const payload = await response.json(); - if (response.ok) return payload; - log.debug('handleResponse error ---', response.status, payload); + if (response.ok) return payload; // pass along user errors return Promise.reject({ status: response.status, - message: payload.error, + message: payload.error || payload.message, }); } diff --git a/src/api/treeTrackerApi.js b/src/api/treeTrackerApi.js index f1480e7d0..0516b7d11 100644 --- a/src/api/treeTrackerApi.js +++ b/src/api/treeTrackerApi.js @@ -46,8 +46,6 @@ export default { delete where.active; delete where.approved; - log.debug('getRawCaptures where -->', where); - const filterObj = { ...where, limit: rowsPerPage, @@ -68,32 +66,53 @@ export default { handleError(error); } }, - approveCaptureImage(capture, morphology, age, captureApprovalTag, speciesId) { + getRawCaptureCount({ filter }, abortController) { try { - log.debug('approveCaptureImage', capture, captureApprovalTag); + const where = filter.getWhereObj(); + where.status = + STATUS_STATES[getVerificationStatus(where.active, where.approved)]; + delete where.active; + delete where.approved; - // map legacy data to fields for new microservice + const filterObj = { ...where }; + + const query = `${QUERY_API}/raw-captures/count${ + filterObj ? `?${this.makeQueryString(filterObj)}` : '' + }`; + + return fetch(query, { + headers: { + Authorization: session.token, + }, + signal: abortController?.signal, + }).then(handleResponse); + } catch (error) { + handleError(error); + } + }, + approveCaptureImage(capture, morphology, age, speciesId) { + try { + // Note: not all raw-capture fields are added to a capture const newCapture = { - id: capture.uuid, - reference_id: capture.id, - session_id: capture.session_id, // no legacy equivalent - planterId: capture.planterId, // legacy only - grower_account_id: capture.grower_account_id, // no legacy equivalent + id: capture.id, + reference_id: capture.reference_id, + session_id: capture.session_id, + grower_account_id: capture.grower_account_id, planting_organization_id: capture.organization_id, - device_configuration_id: capture.device_configuration_id, // no legacy equivalent - image_url: capture.imageUrl, + device_configuration_id: capture.device_configuration_id, + image_url: capture.image_url, lat: capture.lat, lon: capture.lon, gps_accuracy: capture.gps_accuracy, - captured_at: capture.timeCreated, - note: capture.note, + captured_at: capture.captured_at, + note: capture.note ? capture.note : null, age: age, morphology, species_id: speciesId, }; // add the new capture - fetch(`${TREETRACKER_API}/captures`, { + return fetch(`${TREETRACKER_API}/captures`, { method: 'POST', headers: { 'content-type': 'application/json', @@ -105,21 +124,19 @@ export default { handleError(error); } }, - rejectCaptureImage(capture, rejectionReason) { + async rejectCaptureImage(capture, rejectionReason) { try { - log.debug('reject capture', capture.uuid, rejectionReason); - const query = `${FIELD_DATA_API}/raw-captures/${capture.uuid}`; - return fetch(query, { + log.debug('reject capture', capture.id, rejectionReason); + const query = `${FIELD_DATA_API}/raw-captures/${capture.id}/reject`; + const data = await fetch(query, { method: 'PATCH', headers: { 'content-type': 'application/json', Authorization: session.token, }, - body: JSON.stringify({ - status: 'rejected', - rejection_reason: rejectionReason, - }), + body: JSON.stringify({ rejection_reason: rejectionReason }), }).then(handleResponse); + return data; } catch (error) { handleError(error); } diff --git a/src/components/Verify.js b/src/components/Verify.js index 08ac460a9..de672e10e 100644 --- a/src/components/Verify.js +++ b/src/components/Verify.js @@ -266,11 +266,15 @@ const Verify = (props) => { } /* - * create new tags and return all the applied tags + * if approved, create new tags and return all the applied tags */ - const tags = await tagsContext.createTags(); - approveAction.tags = tags.map((t) => t.id); + if (approveAction.isApproved) { + const tags = await tagsContext.createTags(); + log.debug('TAGS -->', tags); + approveAction.tags = tags.map((t) => t.id); + } const result = await verifyContext.approveAll(approveAction); + log.debug('APPROVED captures --->', result); if (!result) { window.alert('Failed to approve/reject a capture'); } else if (!approveAction.rememberSelection) { @@ -355,7 +359,7 @@ const Verify = (props) => { width: `calc(100% / ${idx ? idx : 1})`, }, }; - const key = `@media (min-width: ${WIDTH * idx + SIDE_PANEL_WIDTH}px) + const key = `@media (min-width: ${WIDTH * idx + SIDE_PANEL_WIDTH}px) and (max-width: ${ WIDTH * (idx + 1) + SIDE_PANEL_WIDTH }px)`; diff --git a/src/context/SpeciesContext.js b/src/context/SpeciesContext.js index 3f9af0600..9bfc790b2 100644 --- a/src/context/SpeciesContext.js +++ b/src/context/SpeciesContext.js @@ -80,7 +80,7 @@ export function SpeciesProvider(props) { if (a) { return a; } else if (c.name === speciesInput) { - return c.id; + return c.uuid; } else { return a; } diff --git a/src/context/VerifyContext.js b/src/context/VerifyContext.js index 2e91b021f..c93cb5242 100644 --- a/src/context/VerifyContext.js +++ b/src/context/VerifyContext.js @@ -110,22 +110,23 @@ export function VerifyProvider(props) { } if (approveAction.isApproved) { log.debug('approve'); - await api.approveCaptureImage( + const result = await api.approveCaptureImage( capture, approveAction.morphology, approveAction.age, - approveAction.captureApprovalTag, approveAction.speciesId ); + + log.debug('approved', result); + + if (approveAction.tags) { + await api.createCaptureTags(capture.id, approveAction.tags); + } } else { log.debug('reject'); await api.rejectCaptureImage(capture, approveAction.rejectionReason); } - if (approveAction.tags) { - await api.createCaptureTags(capture.uuid, approveAction.tags); - } - return true; }; @@ -146,7 +147,7 @@ export function VerifyProvider(props) { rowsPerPage: pageSize, filter: filter, }; - log.debug('load page with params:', pageParams); + const result = await api.getRawCaptures(pageParams, abortController); setCaptureImages(result?.raw_captures || []); setCaptureCount(Number(result?.total)); @@ -210,16 +211,16 @@ export function VerifyProvider(props) { }; const approveAll = async (approveAction) => { - log.debug('approveAll with approveAction:', approveAction); - setIsLoading(true); - setIsApproveAllProcessing(true); - const captureSelected = getCaptureSelectedArr(); - const total = captureSelected.length; - const undo = captureImages.filter((capture) => - captureSelected.some((id) => id === capture.id) - ); - log.debug('items:%d', captureImages.length); try { + log.debug('approveAll items:%d', captureImages.length); + setIsLoading(true); + setIsApproveAllProcessing(true); + const captureSelected = getCaptureSelectedArr(); + const total = captureSelected.length; + const undo = captureImages.filter((capture) => + captureSelected.some((id) => id === capture.id) + ); + for (let i = 0; i < total; i++) { const captureId = captureSelected[i]; const capture = captureImages.reduce((a, c) => { @@ -232,35 +233,34 @@ export function VerifyProvider(props) { const currentFilter = filter.getWhereObj(); capture.organization_id = currentFilter.organizationId || getOrganizationUUID(); - log.debug( - 'organization_id:', - currentFilter.organizationId, - getOrganizationUUID(), - capture.organization_id - ); - log.debug('approve:%d', capture.id); - log.trace('approve:%d', capture.id); + // log.debug( + // 'organization_id:', + // currentFilter.organizationId, + // getOrganizationUUID(), + // capture.organization_id + // ); await approve({ capture, approveAction, }); setApproveAllComplete(100 * ((i + 1) / total)); } + + //push to undo list and set status flags + setCaptureImagesUndo(undo), setIsLoading(false); + await loadCaptureImages(); + setIsApproveAllProcessing(false); + setApproveAllComplete(0); + setInvalidateCaptureCount(true); + + resetSelection(); + return true; } catch (e) { log.warn('get error:', e); setIsLoading(false); setIsApproveAllProcessing(false); return false; } - //push to undo list and set status flags - setCaptureImagesUndo(undo), setIsLoading(false); - await loadCaptureImages(); - setIsApproveAllProcessing(false); - setApproveAllComplete(0); - setInvalidateCaptureCount(true); - - resetSelection(); - return true; }; const undoAll = async () => { @@ -304,15 +304,13 @@ export function VerifyProvider(props) { }; const getCaptureCount = async (newfilter = filter) => { - log.debug('-- verify getCaptureCount'); - const pageParams = { page: currentPage, rowsPerPage: pageSize, filter: newfilter, }; - const result = await api.getRawCaptures(pageParams); - setCaptureCount(Number(result?.total)); + const result = await api.getRawCaptureCount(pageParams); + setCaptureCount(Number(result?.count)); setInvalidateCaptureCount(false); };