diff --git a/cypress/e2e/patient_spec/PatientInvestigation.cy.ts b/cypress/e2e/patient_spec/PatientInvestigation.cy.ts index 27d68aa257f..8f5ac03a9ef 100644 --- a/cypress/e2e/patient_spec/PatientInvestigation.cy.ts +++ b/cypress/e2e/patient_spec/PatientInvestigation.cy.ts @@ -1,13 +1,30 @@ -import { PatientPage } from "pageobject/Patient/PatientCreation"; -import PatientInvestigation from "pageobject/Patient/PatientInvestigation"; +import { advanceFilters } from "pageobject/utils/advanceFilterHelpers"; +import { pageNavigation } from "pageobject/utils/paginationHelpers"; import LoginPage from "../../pageobject/Login/LoginPage"; +import PatientHome from "../../pageobject/Patient/PatientHome"; -describe("Patient Investigation Creation from Patient consultation page", () => { +describe("Patient Homepage present functionalities", () => { const loginPage = new LoginPage(); - const patientPage = new PatientPage(); - const patientInvestigation = new PatientInvestigation(); - const patientName = "Dummy Patient Thirteen"; + const patientHome = new PatientHome(); + const patientGender = "Male"; + const patientCategory = "Moderate"; + const patientMinimumAge = "18"; + const patientMaximumAge = "24"; + const patientLastAdmittedBed = "No bed assigned"; + const PatientLastConsentType = "No consents"; + const patientTelemedicinePerference = "No"; + const patientReviewStatus = "No"; + const patientMedicoStatus = "Non-Medico-Legal"; + const patientIcdDiagnosis = "1A00"; + const facilityName = "Dummy Facility 40"; + const facilityType = "Private Hospital"; + const facilityLsgBody = "Aikaranad Grama Panchayat, Ernakulam District"; + const facilityDistrict = "Ernakulam"; + const patientFromDate = "01122023"; + const patientToDate = "07122023"; + const patientFromDateBadge = "2023-12-01"; + const patientToDateBadge = "2023-12-07"; before(() => { loginPage.loginByRole("districtAdmin"); @@ -20,18 +37,140 @@ describe("Patient Investigation Creation from Patient consultation page", () => cy.awaitUrl("/patients"); }); - it("Create a investigation for a patient and verify its reflection", () => { - patientPage.visitPatient(patientName); - patientInvestigation.clickInvestigationTab(); - patientInvestigation.clickLogLabResults(); - patientInvestigation.selectInvestigationOption([ - "Haematology", - "Urine Test", - ]); - cy.clickSubmitButton("Save Investigation"); - cy.verifyNotification("Please Enter at least one value"); + it("Date based advance filters applied in the patient tab", () => { + advanceFilters.clickAdvancedFiltersButton(); + patientHome.typePatientCreatedBeforeDate(patientFromDate); + patientHome.typePatientCreatedAfterDate(patientToDate); + patientHome.typePatientModifiedBeforeDate(patientFromDate); + patientHome.typePatientModifiedAfterDate(patientToDate); + patientHome.typePatientAdmitedBeforeDate(patientFromDate); + patientHome.typePatientAdmitedAfterDate(patientToDate); + patientHome.clickPatientFilterApply(); + // verify the badge and clear the count + patientHome.verifyPatientCreatedBeforeDate(patientToDateBadge); + patientHome.verifyPatientCreatedAfterDate(patientFromDateBadge); + patientHome.verifyPatientModifiedBeforeDate(patientToDateBadge); + patientHome.verifyPatientModifiedAfterDate(patientFromDateBadge); + patientHome.verifyPatientAdmittedBeforeDate(patientToDateBadge); + patientHome.verifyPatientAdmittedAfterDate(patientFromDateBadge); + cy.clearAllFilters(); + }); + + it("Facility Geography based advance filters applied in the patient tab", () => { + advanceFilters.clickAdvancedFiltersButton(); + patientHome.typeFacilityName(facilityName); + patientHome.selectFacilityType(facilityType); + patientHome.typeFacilityLsgBody(facilityLsgBody); + patientHome.typeFacilityDistrict(facilityDistrict); + patientHome.clickPatientFilterApply(); + patientHome.verifyTotalPatientCount("1"); + // Clear the badges and verify the patient count along with badges + patientHome.verifyFacilityNameBadgeContent(facilityName); + patientHome.verifyFacilityTypeBadgeContent(facilityType); + patientHome.verifyFacilityLsgBadgeContent(facilityLsgBody); + patientHome.verifyFacilityDistrictContent(facilityDistrict); + cy.clearAllFilters(); + }); + + it("Patient diagnosis based advance filters applied in the patient tab", () => { + // Patient Filtering based on icd-11 data + advanceFilters.clickAdvancedFiltersButton(); + patientHome.selectAnyIcdDiagnosis(patientIcdDiagnosis, patientIcdDiagnosis); + patientHome.selectConfirmedIcdDiagnosis( + patientIcdDiagnosis, + patientIcdDiagnosis, + ); + patientHome.selectUnconfirmedIcdDiagnosis( + patientIcdDiagnosis, + patientIcdDiagnosis, + ); + patientHome.selectProvisionalIcdDiagnosis( + patientIcdDiagnosis, + patientIcdDiagnosis, + ); + patientHome.selectDifferentialIcdDiagnosis( + patientIcdDiagnosis, + patientIcdDiagnosis, + ); + patientHome.clickPatientFilterApply(); + patientHome.verifyTotalPatientCount("0"); + // verify the badges presence in the platform + patientHome.verifyAnyDiagnosisBadgeContent(patientIcdDiagnosis); + patientHome.verifyConfirmedDiagnosisBadgeContent(patientIcdDiagnosis); + patientHome.verifyUnconfirmedDiagnosisBadgeContent(patientIcdDiagnosis); + patientHome.verifyProvisionalDiagnosisBadgeContent(patientIcdDiagnosis); + patientHome.verifyDifferentialDiagnosisBadgeContent(patientIcdDiagnosis); + // Clear the badges and verify the patient count along with badges + cy.clearAllFilters(); + // Apply Any and confirmed diagonsis to verify patient count 17 + advanceFilters.clickAdvancedFiltersButton(); + patientHome.selectAnyIcdDiagnosis(patientIcdDiagnosis, patientIcdDiagnosis); + patientHome.selectConfirmedIcdDiagnosis( + patientIcdDiagnosis, + patientIcdDiagnosis, + ); + patientHome.clickPatientFilterApply(); + patientHome.verifyTotalPatientCount("1"); + }); + + it("Patient Details based advance filters applied in the patient tab", () => { + // Patient Filtering based on patient details + advanceFilters.clickAdvancedFiltersButton(); + patientHome.selectPatientGenderfilter(patientGender); + patientHome.selectPatientCategoryfilter(patientCategory); + patientHome.typePatientMinimumAgeFilter(patientMinimumAge); + patientHome.typePatientMaximumAgeFilter(patientMaximumAge); + patientHome.selectPatientLastAdmittedBed(patientLastAdmittedBed); + patientHome.selectPatientLastConsentType(PatientLastConsentType); + patientHome.selectPatientTelemedicineFilter(patientTelemedicinePerference); + patientHome.selectPatientReviewFilter(patientReviewStatus); + patientHome.selectPatientMedicoFilter(patientMedicoStatus); + patientHome.clickPatientFilterApply(); + cy.get("a[data-cy='patient']").should("contain.text", "Dummy Patient"); + // Verify the presence of badges + patientHome.verifyGenderBadgeContent(patientGender); + patientHome.verifyCategoryBadgeContent(patientCategory); + patientHome.verifyMinAgeBadgeContent(patientMinimumAge); + patientHome.verifyMaxAgeBadgeContent(patientMaximumAge); + patientHome.verifyLastAdmittedBedBadgeContent(patientLastAdmittedBed); + patientHome.verifyLastConsentTypeBadgeContent("No Consents"); + patientHome.verifyTelemedicineBadgeContent("false"); + patientHome.verifyReviewMissedBadgeContent("false"); + patientHome.verifyMedicoBadgeContent("false"); + // Clear the badges and verify the patient count along with badges + cy.clearAllFilters(); + }); + + it("Export the live patient list based on a date range", () => { + patientHome.clickPatientExport(); + cy.verifyNotification("Please select a seven day period"); cy.closeNotification(); - // Temporary workflow for investigation since we dont have dummy data and moving away from existing module + patientHome.typePatientModifiedBeforeDate("01122023"); + patientHome.typePatientModifiedAfterDate("07122023"); + patientHome.clickPatientFilterApply(); + patientHome.interceptPatientExportRequest(); + patientHome.clickPatientExport(); + patientHome.verifyPatientExportRequest(); + }); + + it("Test Pagination on Patient List Page", () => { + let firstPatientPageOne: string; + cy.get('[data-cy="patient"]') + .first() + .invoke("text") + .then((patientOne: string) => { + firstPatientPageOne = patientOne.trim(); + pageNavigation.navigateToNextPage(); + pageNavigation.verifyCurrentPageNumber(2); + cy.get('[data-cy="patient"]') + .first() + .invoke("text") + .then((patientTwo: string) => { + const firstPatientPageTwo = patientTwo.trim(); + expect(firstPatientPageOne).not.to.eq(firstPatientPageTwo); + pageNavigation.navigateToPreviousPage(); + }); + }); }); afterEach(() => { diff --git a/src/components/Facility/Investigations/Reports/index.tsx b/src/components/Facility/Investigations/Reports/index.tsx index f1b27d422d9..853e9f7fa45 100644 --- a/src/components/Facility/Investigations/Reports/index.tsx +++ b/src/components/Facility/Investigations/Reports/index.tsx @@ -1,7 +1,8 @@ import { useCallback, useReducer, useState } from "react"; import { useTranslation } from "react-i18next"; -import ButtonV2 from "@/components/Common/ButtonV2"; +import { Button } from "@/components/ui/button"; + import CircularProgress from "@/components/Common/CircularProgress"; import Loading from "@/components/Common/Loading"; import Page from "@/components/Common/Page"; @@ -53,42 +54,36 @@ const initialState: InitialState = { const investigationReportsReducer = (state = initialState, action: any) => { switch (action.type) { - case "set_investigation_groups": { + case "set_investigation_groups": return { ...state, investigationGroups: action.payload, }; - } - case "set_selected_group": { + case "set_selected_group": return { ...state, selectedGroup: action.payload, }; - } - case "set_investigations": { + case "set_investigations": return { ...state, investigations: action.payload, }; - } - case "set_selected_investigations": { + case "set_selected_investigations": return { ...state, selectedInvestigations: action.payload, }; - } - case "set_investigation_table_data": { + case "set_investigation_table_data": return { ...state, investigationTableData: action.payload, }; - } - case "set_loading": { + case "set_loading": return { ...state, isLoading: action.payload, }; - } default: return state; } @@ -113,6 +108,10 @@ const InvestigationReports = ({ id }: any) => { selectedInvestigations, } = state as InitialState; + const clearSelectedInvestigations = () => { + dispatch({ type: "set_selected_investigations", payload: [] }); + }; + const fetchInvestigationsData = useCallback( async ( onSuccess: ( @@ -314,14 +313,13 @@ const InvestigationReports = ({ id }: any) => { /> {!isLoading.investigationLoading && ( - fetchInvestigation()} disabled={getTestDisabled} variant="primary" - className="my-2.5" > {t("get_tests")} - + )} {!!isLoading.investigationLoading && ( @@ -342,23 +340,31 @@ const InvestigationReports = ({ id }: any) => { }) } optionLabel={(option) => option.name} - optionValue={(option) => option} + optionValue={(option) => option.external_id} isLoading={isLoading.investigationLoading} placeholder={t("select_investigations")} + selectAll={true} /> - - { - setSessionPage(1); - handleGenerateReports(1); - }} - disabled={generateReportDisabled} - variant="primary" - className="my-2.5" - > - {t("generate_report")} - +
+ + +
)} {isLoading.tableData && ( @@ -370,19 +376,19 @@ const InvestigationReports = ({ id }: any) => { {!!investigationTableData.length && ( <>
- handleSessionPage("NEXT")} disabled={prevSessionDisabled} > {isLoading.tableData ? "Loading..." : t("next_sessions")} - - +
{ /> {!loadMoreDisabled && ( - {t("load_more")} - + )} )} diff --git a/src/components/Facility/Investigations/index.tsx b/src/components/Facility/Investigations/index.tsx index da5d93e7ea9..d54a6a5015c 100644 --- a/src/components/Facility/Investigations/index.tsx +++ b/src/components/Facility/Investigations/index.tsx @@ -4,6 +4,8 @@ import { useTranslation } from "react-i18next"; import Card from "@/CAREUI/display/Card"; +import { Button } from "@/components/ui/button"; + import { Submit } from "@/components/Common/ButtonV2"; import Loading from "@/components/Common/Loading"; import Page from "@/components/Common/Page"; @@ -37,10 +39,6 @@ export interface InvestigationType { ideal_value?: string; groups: InvestigationGroup[]; } -type SearchItem = InvestigationGroup | InvestigationType; -function isInvestigation(e: SearchItem): e is InvestigationType { - return (e as InvestigationType).groups !== undefined; -} const testFormReducer = (state = initialState, action: any) => { switch (action.type) { @@ -93,7 +91,7 @@ const Investigation = (props: { name: investigation.split(" -- ")[0], groups: investigation .split(" -- ")[1] - .split(",") + .split(", ") .map((group) => group.split("( ")[1].split(" )")[0]), }; }, @@ -106,8 +104,6 @@ const Investigation = (props: { >([]); const [saving, setSaving] = useState(false); const [session, setSession] = useState(""); - const [selectedItems, selectItems] = useState([]); - const { data: investigations, loading: listInvestigationDataLoading } = useTanStackQueryInstead(routes.listInvestigations, {}); @@ -150,7 +146,6 @@ const Investigation = (props: { const investigation = investigations.results.find( (investigation) => investigation.name === inv.name, ); - // check if investigation contains all groups if ( inv.groups.every((group: string) => investigation?.groups.find( @@ -173,7 +168,6 @@ const Investigation = (props: { .flat(), ]; setSelectedGroup(Array.from(new Set(allGroups))); - selectItems([...prefilledGroups, ...prefilledInvestigations]); } }, [investigations, investigationGroups]); @@ -262,39 +256,58 @@ const Investigation = (props: { [patientId]: { name: patientData?.name }, }} > -
- option.name} - optionValue={(option) => option} - onChange={({ value }) => { - selectItems(value); - setSelectedInvestigations(value.filter(isInvestigation)); - setSelectedGroup( - [ - ...value - .filter((e) => !isInvestigation(e)) - .map((e) => e.external_id), - ...value.reduce( - (acc, option) => - acc.concat( - isInvestigation(option) - ? option.groups.map((e) => e.external_id) - : [], - ), - [], - ), - ].filter((v, i, a) => a.indexOf(v) == i), - ); - }} - /> +
+
+ inv.external_id)} + onChange={({ value }) => { + const selectedValues = Array.isArray(value) ? value : [value]; + const newSelectedInvestigations = selectedValues + .map((val) => + investigations?.results.find( + (inv) => inv.external_id === val, + ), + ) + .filter((inv): inv is InvestigationType => inv !== undefined); + + setSelectedInvestigations(newSelectedInvestigations); + + const groupIds = newSelectedInvestigations.reduce( + (acc, inv) => acc.concat(inv.groups.map((g) => g.external_id)), + [], + ); + setSelectedGroup(Array.from(new Set(groupIds))); + }} + optionLabel={(option) => option.name} + optionValue={(option) => option.external_id} + placeholder={t("select_investigations")} + selectAll + className="w-full" + /> +
+ +
+ + {selectedInvestigations.length > 0 && ( + + )} +
{selectedGroup.map((group_id) => { const currentGroupsInvestigations = selectedInvestigations.filter( @@ -305,7 +318,7 @@ const Investigation = (props: { : listOfInvestigations(group_id, investigations?.results || []); const group = findGroup(group_id, investigationGroups?.results || []); return ( - + ); })} - -
- -
);