Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: New Equipment Codes #847

Merged
merged 15 commits into from
Jan 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified backend/templates/complaint/CDOGS-HWCR-COMPLAINT-TEMPLATE-v1.docx
Binary file not shown.
4 changes: 2 additions & 2 deletions frontend/cypress/e2e/hwcr-outcome-equipment.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ describe("HWCR Outcome Equipment", () => {
officer: "TestAcct, ENV",
date: "01",
toastText: "Equipment has been updated",
equipmentType: "Bear snare",
equipmentType: "Neck snare",
};
cy.get("#equipment-copy-address-button").click();
cy.get("#copy-coordinates-button").click();
Expand All @@ -87,7 +87,7 @@ describe("HWCR Outcome Equipment", () => {
officer: "TestAcct, ENV",
date: "02",
toastText: "Equipment has been updated",
equipmentType: "Bear live trap",
equipmentType: "Live trap",
};

cy.fillInHWCSection(sectionParams).then(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
selectComplaintStatusWithPendingCodeDropdown,
selectGirTypeCodeDropdown,
selectComplaintReceivedMethodDropdown,
selectWildlifeComplaintOutcome,
selectAllWildlifeComplaintOutcome,
} from "@store/reducers/code-table";
import { selectOfficersByAgencyDropdownUsingPersonGuid } from "@store/reducers/officer";
import { selectDecisionTypeDropdown } from "@store/reducers/code-table-selectors";
Expand Down Expand Up @@ -63,7 +63,7 @@ export const ComplaintFilter: FC<Props> = ({ type }) => {
const statusTypes = useAppSelector(selectComplaintStatusWithPendingCodeDropdown);
const violationTypes = useAppSelector(selectViolationCodeDropdown(agency));
const girTypes = useAppSelector(selectGirTypeCodeDropdown);
const outcomeAnimalTypes = useAppSelector(selectWildlifeComplaintOutcome);
const outcomeAnimalTypes = useAppSelector(selectAllWildlifeComplaintOutcome); //want to see inactive items in the filter

const regions = useAppSelector(selectCascadedRegion(region?.value, zone?.value, community?.value));
const zones = useAppSelector(selectCascadedZone(region?.value, zone?.value, community?.value));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ToastContainer } from "react-toastify";

import { useAppDispatch, useAppSelector } from "@hooks/hooks";
import { selectOfficerListByAgency, selectOfficersByAgency } from "@store/reducers/officer";
import { selectEquipmentDropdown, selectTrapEquipment } from "@store/reducers/code-table";
import { selectActiveEquipmentDropdown, selectTrapEquipment } from "@store/reducers/code-table";
import { getComplaintById, selectComplaint, selectComplaintCallerInformation } from "@store/reducers/complaints";
import { CompSelect } from "@components/common/comp-select";
import { ToggleError } from "@common/toast";
Expand Down Expand Up @@ -60,22 +60,19 @@ export const EquipmentForm: FC<EquipmentFormProps> = ({ equipment, assignedOffic
const complaintData = useAppSelector(selectComplaint);
const { ownedByAgencyCode } = useAppSelector(selectComplaintCallerInformation);
const officersInAgencyList = useAppSelector(selectOfficersByAgency(ownedByAgencyCode?.agency));
const equipmentDropdownOptions = useAppSelector(selectEquipmentDropdown);
const equipmentDropdownOptions = useAppSelector(selectActiveEquipmentDropdown);
const trapEquipment = useAppSelector(selectTrapEquipment);
const assignableOfficers = useAppSelector(selectOfficerListByAgency);

const isInEdit = useAppSelector((state) => state.cases.isInEdit);
const showSectionErrors = isInEdit.showSectionErrors;

// needed to turn equipment type codes into descriptions
const equipmentTypeCodes = useAppSelector(selectEquipmentDropdown);

// for turning codes into values
const getValue = useCallback(
(property: string): Option | undefined => {
return equipmentTypeCodes.find((item) => item.value === equipment?.typeCode);
return equipmentDropdownOptions.find((item) => item.value === equipment?.typeCode);
},
[equipmentTypeCodes, equipment?.typeCode],
[equipmentDropdownOptions, equipment?.typeCode],
);

useEffect(() => {
Expand Down Expand Up @@ -397,7 +394,7 @@ export const EquipmentForm: FC<EquipmentFormProps> = ({ equipment, assignedOffic
className="comp-details-form-row"
id="equipment-officer-set-div"
>
<label htmlFor="equipment-officer-set-select">Set by</label>
<label htmlFor="equipment-officer-set-select">Set/Used by</label>
<div className="comp-details-input full-width">
<CompSelect
id="equipment-officer-set-select"
Expand All @@ -417,7 +414,7 @@ export const EquipmentForm: FC<EquipmentFormProps> = ({ equipment, assignedOffic
className="comp-details-form-row"
id="equipment-date-set-div"
>
<label htmlFor="equipment-day-set">Set date</label>
<label htmlFor="equipment-day-set">Set/Used date</label>
<div className="comp-details-input">
<ValidationDatePicker
id="equipment-day-set"
Expand All @@ -433,7 +430,7 @@ export const EquipmentForm: FC<EquipmentFormProps> = ({ equipment, assignedOffic
</div>

{/* REMOVED BY */}
{officerSet && dateSet && (
{officerSet && dateSet && type?.value !== "K9UNT" && type?.value !== "LLTHL" && (
<>
<div
className="comp-details-form-row"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { useAppDispatch, useAppSelector } from "@hooks/hooks";

import Option from "@apptypes/app/option";

import { selectEquipmentDropdown } from "@store/reducers/code-table";
import { selectAllEquipmentDropdown } from "@store/reducers/code-table";
import { CASE_ACTION_CODE } from "@constants/case_actions";
import { deleteEquipment } from "@store/reducers/case-thunks";
import { CompLocationInfo } from "@components/common/comp-location-info";
Expand Down Expand Up @@ -41,7 +41,7 @@ export const EquipmentItem: FC<EquipmentItemProps> = ({ equipment, isEditDisable
}
};

const equipmentTypeCodes = useAppSelector(selectEquipmentDropdown);
const equipmentTypeCodes = useAppSelector(selectAllEquipmentDropdown); //Want to be able to display inactive equipment

const setEquipmentActor = equipment.actions?.findLast(
(action) => action.actionCode === CASE_ACTION_CODE.SETEQUIPMT,
Expand Down Expand Up @@ -72,6 +72,8 @@ export const EquipmentItem: FC<EquipmentItemProps> = ({ equipment, isEditDisable
!removedEquipmentDate &&
getValue("equipment")?.value !== "SIGNG" &&
getValue("equipment")?.value !== "TRCAM" &&
getValue("equipment")?.value !== "LLTHL" &&
getValue("equipment")?.value !== "K9UNT" &&
isInEdit.showSectionErrors;

return (
Expand All @@ -88,7 +90,7 @@ export const EquipmentItem: FC<EquipmentItemProps> = ({ equipment, isEditDisable
confirmText="Yes, delete equipment"
/>
<Card
className={`comp-equipment-card ${!removedEquipmentFullName ? "active" : "inactive"}`}
className={`comp-equipment-card ${!removedEquipmentFullName && equipment.typeCode !== "K9UNT" && equipment.typeCode !== "LLTHL" ? "active" : "inactive"}`}
border={showSectionErrors ? "danger" : "default"}
>
<Card.Body>
Expand All @@ -103,7 +105,9 @@ export const EquipmentItem: FC<EquipmentItemProps> = ({ equipment, isEditDisable
<div className="comp-equipment-item-header">
<div className="comp-equipment-item-header-title">
<h4 id="equipment-type-title">{getValue("equipment")?.label}</h4>
{!removedEquipmentFullName && <Badge bg="success">Active</Badge>}
{!removedEquipmentFullName && equipment.typeCode !== "K9UNT" && equipment.typeCode !== "LLTHL" && (
<Badge bg="success">Active</Badge>
)}
</div>
<div className="comp-equipment-item-header-actions">
<Button
Expand Down Expand Up @@ -141,29 +145,32 @@ export const EquipmentItem: FC<EquipmentItemProps> = ({ equipment, isEditDisable
/>
<br />
<div>
<dt>Set by</dt>
<dt>Set/Used by</dt>
<dd>
<span id="equipment-officer-set-div">{setEquipmentFullName}</span>
</dd>
</div>
<div>
<dt>Date set</dt>
<dt>Set/Used date</dt>
<dd id="equipment-date-set-div">{formatDate(setEquipmentDate?.toString())}</dd>
</div>
{equipment.id && removedEquipmentActor && (
<>
<div>
<dt>Removed by</dt>
<dd>
<span id="comp-details-assigned-officer-name-text-id">{removedEquipmentFullName}</span>
</dd>
</div>
<div>
<dt>Removal date</dt>
<dd id="equipment-removal-date">{formatDate(removedEquipmentDate?.toString())}</dd>
</div>
</>
)}
{equipment.id &&
removedEquipmentActor &&
equipment.typeCode !== "K9UNT" &&
equipment.typeCode !== "LLTHL" && (
<>
<div>
<dt>Removed by</dt>
<dd>
<span id="comp-details-assigned-officer-name-text-id">{removedEquipmentFullName}</span>
</dd>
</div>
<div>
<dt>Removal date</dt>
<dd id="equipment-removal-date">{formatDate(removedEquipmentDate?.toString())}</dd>
</div>
</>
)}
{equipment.id && ["Y", "N"].includes(equipment?.wasAnimalCaptured) && (
<div>
<dt>Was animal captured?</dt>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
selectSexDropdown,
selectSpeciesCodeDropdown,
selectThreatLevelDropdown,
selectWildlifeComplaintOutcome,
selectAllWildlifeComplaintOutcome,
} from "@store/reducers/code-table";
import { from } from "linq-to-typescript";
import { BsExclamationCircleFill } from "react-icons/bs";
Expand All @@ -32,7 +32,7 @@ export const AnimalOutcome: FC<props> = ({ index, data, agency, edit, remove })
const sexes = useAppSelector(selectSexDropdown);
const ages = useAppSelector(selectAgeDropdown);
const threatLevels = useAppSelector(selectThreatLevelDropdown);
const outcomes = useAppSelector(selectWildlifeComplaintOutcome);
const outcomes = useAppSelector(selectAllWildlifeComplaintOutcome); //want to display inactive items
const officers = useAppSelector(selectOfficerListByAgency);
const isLargeCarnivore = useAppSelector(selectComplaintLargeCarnivoreInd);
const isInEdit = useAppSelector((state) => state.cases.isInEdit);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
selectSexDropdown,
selectSpeciesCodeDropdown,
selectThreatLevelDropdown,
selectWildlifeComplaintOutcome,
selectActiveWildlifeComplaintOutcome,
} from "@store/reducers/code-table";
import { AnimalOutcome } from "@apptypes/app/complaints/outcomes/wildlife/animal-outcome";
import { AnimalTagV2 } from "@apptypes/app/complaints/outcomes/wildlife/animal-tag";
Expand Down Expand Up @@ -66,7 +66,7 @@ export const CreateAnimalOutcome: FC<props> = ({ index, assignedOfficer: officer
const sexes = useAppSelector(selectSexDropdown);
const ages = useAppSelector(selectAgeDropdown);
const threatLevels = useAppSelector(selectThreatLevelDropdown);
const outcomes = useAppSelector(selectWildlifeComplaintOutcome);
const outcomes = useAppSelector(selectActiveWildlifeComplaintOutcome);
const officers = useAppSelector(selectOfficerListByAgency);
const isLargeCarnivore = useAppSelector(selectComplaintLargeCarnivoreInd);
const isInEdit = useAppSelector((state) => state.cases.isInEdit);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
selectSexDropdown,
selectAgeDropdown,
selectThreatLevelDropdown,
selectWildlifeComplaintOutcome,
selectActiveWildlifeComplaintOutcome,
} from "@store/reducers/code-table";
import { selectOfficerListByAgency } from "@store/reducers/officer";
import { Button, Card, ListGroup } from "react-bootstrap";
Expand Down Expand Up @@ -60,7 +60,7 @@ export const EditOutcome: FC<props> = ({ id, index, outcome, assignedOfficer: of
const sexes = useAppSelector(selectSexDropdown);
const ages = useAppSelector(selectAgeDropdown);
const threatLevels = useAppSelector(selectThreatLevelDropdown);
const outcomes = useAppSelector(selectWildlifeComplaintOutcome);
const outcomes = useAppSelector(selectActiveWildlifeComplaintOutcome);
const officers = useAppSelector(selectOfficerListByAgency);
const isInEdit = useAppSelector((state) => state.cases.isInEdit);
const isLargeCarnivore = useAppSelector(selectComplaintLargeCarnivoreInd);
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/app/hooks/validate-complaint.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,11 @@ const useValidateComplaint = () => {
const equipmentCriteria =
equipment?.find(
(item: EquipmentDetailsDto) =>
item.wasAnimalCaptured === "U" && item.typeCode !== "SIGNG" && item.typeCode !== "TRCAM",
item.wasAnimalCaptured === "U" &&
item.typeCode !== "SIGNG" &&
item.typeCode !== "TRCAM" &&
item.typeCode !== "LLTHL" &&
item.typeCode !== "K9UNT",
) === undefined;

//check Animal has outcome, officer and date
Expand Down
55 changes: 42 additions & 13 deletions frontend/src/app/store/reducers/code-table.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PayloadAction, createSlice } from "@reduxjs/toolkit";
import { PayloadAction, createSelector, createSlice } from "@reduxjs/toolkit";
import { AppThunk, RootState, store } from "@store/store";
import { from } from "linq-to-typescript";
import config from "@/config";
Expand Down Expand Up @@ -1337,7 +1337,25 @@ export const selectEarDropdown = (state: RootState): Array<Option> => {
return data;
};

export const selectWildlifeComplaintOutcome = (state: RootState): Array<Option> => {
//Used for drop downs on Create / Edit
export const selectActiveWildlifeComplaintOutcome = (state: RootState): Array<Option> => {
const {
codeTables: { "wildlife-outcomes": items },
} = state;

let filteredItems = items.filter((item) => item.isActive === true); // Only items with active_ind = true

// Map the filtered and sorted items to the Option format
const data = filteredItems.map(({ outcome: value, shortDescription: label }) => {
const item: Option = { label, value };
return item;
});

return data;
};

//Used for filter dropdown and View State (could be legacy data)
export const selectAllWildlifeComplaintOutcome = (state: RootState): Array<Option> => {
const {
codeTables: { "wildlife-outcomes": items },
} = state;
Expand Down Expand Up @@ -1389,18 +1407,29 @@ export const selectRemainingDrugUse = (state: RootState): Array<Option> => {
return data;
};

export const selectEquipmentDropdown = (state: RootState): Array<Option> => {
const {
codeTables: { equipment: items },
} = state;
export const selectActiveEquipmentDropdown = createSelector(
(state: RootState) => state.codeTables.equipment,
(items) => {
let filteredItems = items.filter((item) => item.isActive === true); // Only items with active_ind = true

const data = items.map(({ equipment: value, shortDescription: label }) => {
const item: Option = { label, value };
return item;
});

return data;
};
// Map the filtered items to the Option format
return filteredItems.map(({ equipment: value, shortDescription: label }) => ({
label,
value,
}));
},
);

export const selectAllEquipmentDropdown = createSelector(
(state: RootState) => state.codeTables.equipment,
(items) => {
// Map the filtered items to the Option format
return items.map(({ equipment: value, shortDescription: label }) => ({
label,
value,
}));
},
);

export const selectLocationDropdown = (state: RootState): Array<Option> => {
const {
Expand Down
Loading