diff --git a/src/common/variables.js b/src/common/variables.js
index 2a9ab80c2..c3e9f258b 100644
--- a/src/common/variables.js
+++ b/src/common/variables.js
@@ -10,6 +10,11 @@ export const tokenizationStates = {
TOKENIZED: 'Tokenized',
NOT_TOKENIZED: 'Not Tokenized',
};
+export const verificationStatesArr = [
+ verificationStates.APPROVED,
+ verificationStates.AWAITING,
+ verificationStates.REJECTED,
+];
// These are the default min/max dates for the MUI KeyboardDatePicker component
// See https://material-ui-pickers.dev/api/KeyboardDatePicker
diff --git a/src/components/CaptureFilter.js b/src/components/CaptureFilter.js
index 42e805b83..1c41ab443 100644
--- a/src/components/CaptureFilter.js
+++ b/src/components/CaptureFilter.js
@@ -4,6 +4,9 @@ import Grid from '@material-ui/core/Grid';
import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';
import MenuItem from '@material-ui/core/MenuItem';
+import Checkbox from '@material-ui/core/Checkbox';
+import ListItemIcon from '@material-ui/core/ListItemIcon';
+import ListItemText from '@material-ui/core/ListItemText';
import Autocomplete from '@material-ui/lab/Autocomplete';
import FilterModel, {
ALL_SPECIES,
@@ -25,9 +28,9 @@ import {
import {
verificationStates,
tokenizationStates,
+ verificationStatesArr,
datePickerDefaultMinDate,
} from '../common/variables';
-import { getVerificationStatus } from '../common/utils';
import { AppContext } from '../context/AppContext';
import { SpeciesContext } from '../context/SpeciesContext';
import { TagsContext } from '../context/TagsContext';
@@ -72,7 +75,6 @@ const styles = (theme) => {
};
function Filter(props) {
- // console.log('render: filter top');
const speciesContext = useContext(SpeciesContext);
const tagsContext = useContext(TagsContext);
const { orgList, userHasOrg } = useContext(AppContext);
@@ -85,21 +87,30 @@ function Filter(props) {
const [growerId, setGrowerId] = useState(filter?.planterId || '');
const [deviceId, setDeviceId] = useState(filter?.deviceIdentifier || '');
const [growerIdentifier, setGrowerIdentifier] = useState(
- filter?.planterIdentifier || '',
+ filter?.planterIdentifier || ''
);
- const [approved, setApproved] = useState(filter?.approved);
- const [active, setActive] = useState(filter?.active);
+ const [verifyStatus, setVerifyStatus] = useState([
+ { active: true, approved: true },
+ { active: true, approved: false },
+ ]);
const [dateStart, setDateStart] = useState(
- filter?.dateStart || dateStartDefault,
+ filter?.dateStart || dateStartDefault
);
const [dateEnd, setDateEnd] = useState(filter?.dateEnd || dateEndDefault);
const [speciesId, setSpeciesId] = useState(filter?.speciesId || ALL_SPECIES);
const [tag, setTag] = useState(null);
const [tagSearchString, setTagSearchString] = useState('');
const [organizationId, setOrganizationId] = useState(
- filter.organizationId || ALL_ORGANIZATIONS,
+ filter.organizationId || ALL_ORGANIZATIONS
);
const [tokenId, setTokenId] = useState(filter?.tokenId || filterOptionAll);
+ const [verificationStatus, setVerificationStatus] = useState([
+ verificationStates.APPROVED,
+ verificationStates.AWAITING,
+ ]);
+ const isAllVerification =
+ verificationStatus.length &&
+ verificationStatus.length === verificationStatesArr.length;
const handleDateStartChange = (date) => {
setDateStart(date);
@@ -113,6 +124,34 @@ function Filter(props) {
return convertDateToDefaultSqlDate(date);
};
+ const handleVerificationStatusChange = (event) => {
+ let value = event.target.value;
+ let status = [];
+ if (
+ value[value.length - 1] === 'all' ||
+ (value.length === 3 && value[value.length - 1] !== 'all')
+ ) {
+ setVerificationStatus(
+ verificationStatus.length === verificationStatesArr.length
+ ? []
+ : verificationStatesArr
+ );
+ value = verificationStatesArr;
+ } else {
+ setVerificationStatus(value);
+ }
+ value.forEach((val) => {
+ if (val === verificationStates.APPROVED) {
+ status.push({ active: true, approved: true });
+ } else if (val === verificationStates.AWAITING) {
+ status.push({ active: true, approved: false });
+ } else if (val === verificationStates.REJECTED) {
+ status.push({ active: false, approved: false });
+ }
+ });
+ setVerifyStatus(status);
+ };
+
function handleSubmit(e) {
e.preventDefault();
// save the filer to context for editing & submit
@@ -124,12 +163,11 @@ function Filter(props) {
filter.planterIdentifier = growerIdentifier;
filter.dateStart = dateStart ? formatDate(dateStart) : undefined;
filter.dateEnd = dateEnd ? formatDate(dateEnd) : undefined;
- filter.approved = approved;
- filter.active = active;
filter.speciesId = speciesId;
filter.tagId = tag ? tag.id : 0;
filter.organizationId = organizationId;
filter.tokenId = tokenId;
+ filter.verifyStatus = verifyStatus;
props.onSubmit && props.onSubmit(filter);
}
@@ -147,10 +185,11 @@ function Filter(props) {
setTagSearchString('');
setOrganizationId(ALL_ORGANIZATIONS);
setTokenId(filterOptionAll);
-
+ setVerifyStatus([
+ { active: true, approved: true },
+ { active: true, approved: false },
+ ]);
const filter = new FilterModel();
- filter.approved = approved; // keeps last value set
- filter.active = active; // keeps last value set
props.onSubmit && props.onSubmit(filter);
}
@@ -186,38 +225,36 @@ function Filter(props) {
htmlFor="verification-status"
id="verification-status"
label="Verification Status"
- value={
- active === undefined && approved === undefined
- ? filterOptionAll
- : getVerificationStatus(active, approved)
- }
- onChange={(e) => {
- setApproved(
- e.target.value === filterOptionAll
- ? undefined
- : e.target.value === verificationStates.AWAITING ||
- e.target.value === verificationStates.REJECTED
- ? false
- : true,
- );
- setActive(
- e.target.value === filterOptionAll
- ? undefined
- : e.target.value === verificationStates.AWAITING ||
- e.target.value === verificationStates.APPROVED
- ? true
- : false,
- );
+ SelectProps={{
+ multiple: true,
+ value: verificationStatus,
+ onChange: handleVerificationStatusChange,
+ renderValue: (verificationStatus) =>
+ verificationStatus.join(', '),
}}
>
- {[
- filterOptionAll,
- verificationStates.APPROVED,
- verificationStates.AWAITING,
- verificationStates.REJECTED,
- ].map((name) => (
+
+ {verificationStatesArr.map((name) => (
))}
@@ -357,7 +394,7 @@ function Filter(props) {
...tagsContext.tagList.filter((t) =>
t.tagName
.toLowerCase()
- .startsWith(tagSearchString.toLowerCase()),
+ .startsWith(tagSearchString.toLowerCase())
),
]}
value={tag}
@@ -370,7 +407,6 @@ function Filter(props) {
}}
onChange={(_oldVal, newVal) => {
//triggered by onInputChange
- console.log('newVal -- ', newVal);
if (newVal && newVal.tagName === 'Not set') {
setTag('Not set');
} else {
diff --git a/src/components/Captures/CaptureTable.js b/src/components/Captures/CaptureTable.js
index 4fba74c89..e916ddadb 100644
--- a/src/components/Captures/CaptureTable.js
+++ b/src/components/Captures/CaptureTable.js
@@ -226,6 +226,7 @@ const CaptureTable = () => {
columns={columns}
filter={filter}
speciesLookup={speciesLookup}
+ captureTagLookup={captureTagLookup}
/>
{tablePagination()}
@@ -265,7 +266,7 @@ const CaptureTable = () => {
speciesLookup,
captureTagLookup[capture.id] || [],
attr,
- renderer,
+ renderer
)}
))}
@@ -290,7 +291,7 @@ export const formatCell = (
speciesLookup,
additionalTags,
attr,
- renderer,
+ renderer
) => {
if (attr === 'id' || attr === 'planterId') {
return (
diff --git a/src/components/ExportCaptures.js b/src/components/ExportCaptures.js
index c5392e6f0..51cc1f770 100644
--- a/src/components/ExportCaptures.js
+++ b/src/components/ExportCaptures.js
@@ -32,7 +32,14 @@ const useStyle = makeStyles((theme) => ({
}));
const ExportCaptures = (props) => {
- const { isOpen, handleClose, columns, filter, speciesState } = props;
+ const {
+ isOpen,
+ handleClose,
+ columns,
+ filter,
+ speciesLookup,
+ captureTagLookup,
+ } = props;
const classes = useStyle();
let nameColumns = {};
columns.forEach(({ attr, renderer }) => {
@@ -63,9 +70,10 @@ const ExportCaptures = (props) => {
const renderer = selectedColumns[attr].renderer;
formatCapture[attr] = formatCell(
capture,
- speciesState,
+ speciesLookup,
+ captureTagLookup[capture.id] || [],
attr,
- renderer,
+ renderer
);
}
});
@@ -76,7 +84,7 @@ const ExportCaptures = (props) => {
async function downloadCaptures() {
setLoading(true);
const filterColumns = Object.entries(checkedColumns).filter(
- (val) => val[1].status === true,
+ (val) => val[1].status === true
);
const selectedColumns = Object.fromEntries(filterColumns);
await capturesContext.getAllCaptures({ filter }).then((response) => {
diff --git a/src/context/CapturesContext.js b/src/context/CapturesContext.js
index a6b9f7618..4036c00fc 100644
--- a/src/context/CapturesContext.js
+++ b/src/context/CapturesContext.js
@@ -42,9 +42,11 @@ export function CapturesProvider(props) {
// const [byId, setById] = useState({});
const [filter, setFilter] = useState(
new FilterModel({
- approved: true,
- active: true,
- }),
+ verifyStatus: [
+ { active: true, approved: true },
+ { active: true, approved: false },
+ ],
+ })
);
useEffect(() => {
@@ -70,6 +72,29 @@ export function CapturesProvider(props) {
// };
// EVENT HANDLERS
+ const getWhereCondition = () => {
+ const { verifyStatus, ...restFilter } = filter ? filter.getWhereObj() : {};
+ let orCondition = false;
+ let where;
+ if (verifyStatus.length == 1) {
+ where = {
+ ...restFilter,
+ active: verifyStatus[0].active,
+ approved: verifyStatus[0].approved,
+ };
+ } else {
+ orCondition = true;
+ where = [];
+ verifyStatus.forEach((status) => {
+ where.push({
+ ...restFilter,
+ active: status.active,
+ approved: status.approved,
+ });
+ });
+ }
+ return orCondition ? { or: where } : { ...where };
+ };
const queryCapturesApi = ({ id = null, count = false, paramString = null }) =>
// abortController,
@@ -93,9 +118,7 @@ export function CapturesProvider(props) {
const getCaptureCount = async () => {
log.debug('load capture count');
- const paramString = `where=${JSON.stringify(
- filter ? filter.getWhereObj() : {},
- )}`;
+ const paramString = `where=${JSON.stringify(getWhereCondition())}`;
const response = await queryCapturesApi({
count: true,
paramString,
@@ -106,11 +129,9 @@ export function CapturesProvider(props) {
};
const getCapturesAsync = async () => {
- // log.debug('4 - load captures');
- const where = filter ? filter.getWhereObj() : {};
-
+ log.debug('4 - load captures');
const lbFilter = {
- where: { ...where },
+ where: getWhereCondition(),
order: [`${orderBy} ${order}`],
limit: rowsPerPage,
skip: page * rowsPerPage,
@@ -142,12 +163,9 @@ export function CapturesProvider(props) {
console.log('captures filterInfo -- ', filterInfo);
// if filterInfo contains new values override the defaults in state hooks
- const { filter = new FilterModel() } = filterInfo;
-
- const where = filter ? filter.getWhereObj() : {};
const lbFilter = {
- where: { ...where },
+ where: getWhereCondition(),
order: [`${orderBy} ${order}`],
limit: 20000,
fields: {
@@ -179,7 +197,7 @@ export function CapturesProvider(props) {
setCapture(res.data);
})
.catch((err) =>
- console.error(`ERROR: FAILED TO GET SELECTED TREE ${err}`),
+ console.error(`ERROR: FAILED TO GET SELECTED TREE ${err}`)
);
};
diff --git a/src/models/Filter.js b/src/models/Filter.js
index 3e639ff04..214a2b117 100644
--- a/src/models/Filter.js
+++ b/src/models/Filter.js
@@ -24,6 +24,7 @@ export default class Filter {
tagId;
organizationId;
tokenId;
+ verifyStatus;
constructor(options) {
Object.assign(this, options);
@@ -100,6 +101,10 @@ export default class Filter {
where.tokenId = { eq: null };
}
+ if (this.verifyStatus) {
+ where.verifyStatus = this.verifyStatus;
+ }
+
return where;
}