Skip to content

Commit

Permalink
feat: add multi-select dropdown for verification status of captures f… (
Browse files Browse the repository at this point in the history
#212)

* feat: add multi-select dropdown for verification status of captures filter

* feat: setting the active and approved fields based on verification status checkboxes

* fix: update handle change of capture verify status and use or condition in calling captures api

* fix: wrong props params issue in export captures

* fix: move array of verification status to common var utils

* fix: fix handle change of verification status filter in captures
  • Loading branch information
tranquanghuy0801 authored Jan 9, 2022
1 parent 522bd60 commit a67c1dd
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 64 deletions.
5 changes: 5 additions & 0 deletions src/common/variables.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
122 changes: 79 additions & 43 deletions src/components/CaptureFilter.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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';
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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
Expand All @@ -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);
}

Expand All @@ -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);
}

Expand Down Expand Up @@ -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) => (
<MenuItem value="all">
<ListItemIcon>
<Checkbox
checked={
isAllVerification === 0 ? false : isAllVerification
}
indeterminate={
verificationStatus.length > 0 &&
verificationStatus.length < verificationStatesArr.length
}
/>
</ListItemIcon>
<ListItemText primary="Select All" />
</MenuItem>
{verificationStatesArr.map((name) => (
<MenuItem key={name} value={name}>
{name}
<ListItemIcon>
<Checkbox
checked={verificationStatus.indexOf(name) > -1}
/>
</ListItemIcon>
<ListItemText primary={name} />
</MenuItem>
))}
</TextField>
Expand Down Expand Up @@ -357,7 +394,7 @@ function Filter(props) {
...tagsContext.tagList.filter((t) =>
t.tagName
.toLowerCase()
.startsWith(tagSearchString.toLowerCase()),
.startsWith(tagSearchString.toLowerCase())
),
]}
value={tag}
Expand All @@ -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 {
Expand Down
5 changes: 3 additions & 2 deletions src/components/Captures/CaptureTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ const CaptureTable = () => {
columns={columns}
filter={filter}
speciesLookup={speciesLookup}
captureTagLookup={captureTagLookup}
/>
{tablePagination()}
</Grid>
Expand Down Expand Up @@ -265,7 +266,7 @@ const CaptureTable = () => {
speciesLookup,
captureTagLookup[capture.id] || [],
attr,
renderer,
renderer
)}
</TableCell>
))}
Expand All @@ -290,7 +291,7 @@ export const formatCell = (
speciesLookup,
additionalTags,
attr,
renderer,
renderer
) => {
if (attr === 'id' || attr === 'planterId') {
return (
Expand Down
16 changes: 12 additions & 4 deletions src/components/ExportCaptures.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 }) => {
Expand Down Expand Up @@ -63,9 +70,10 @@ const ExportCaptures = (props) => {
const renderer = selectedColumns[attr].renderer;
formatCapture[attr] = formatCell(
capture,
speciesState,
speciesLookup,
captureTagLookup[capture.id] || [],
attr,
renderer,
renderer
);
}
});
Expand All @@ -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) => {
Expand Down
48 changes: 33 additions & 15 deletions src/context/CapturesContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(() => {
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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: {
Expand Down Expand Up @@ -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}`)
);
};

Expand Down
5 changes: 5 additions & 0 deletions src/models/Filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export default class Filter {
tagId;
organizationId;
tokenId;
verifyStatus;

constructor(options) {
Object.assign(this, options);
Expand Down Expand Up @@ -100,6 +101,10 @@ export default class Filter {
where.tokenId = { eq: null };
}

if (this.verifyStatus) {
where.verifyStatus = this.verifyStatus;
}

return where;
}

Expand Down

0 comments on commit a67c1dd

Please sign in to comment.