From 67f9c6e621f9d11ee7b65f95a83e476e71cd6467 Mon Sep 17 00:00:00 2001 From: Manmeet Nagi <143264649+manmeetnagii@users.noreply.github.com> Date: Wed, 11 Dec 2024 11:44:08 +0530 Subject: [PATCH 01/21] fix infinite loading (#9354) --- src/components/Form/AutoCompleteAsync.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Form/AutoCompleteAsync.tsx b/src/components/Form/AutoCompleteAsync.tsx index 48c36258765..1420b02317a 100644 --- a/src/components/Form/AutoCompleteAsync.tsx +++ b/src/components/Form/AutoCompleteAsync.tsx @@ -92,7 +92,7 @@ const AutoCompleteAsync = (props: Props) => { useEffect(() => { fetchDataDebounced(query); - }, [query, fetchDataDebounced]); + }, [query]); return (
From 7ef2299da4dba420c1c8e4c45adedb2fe24064e9 Mon Sep 17 00:00:00 2001 From: JavidSumra <112365664+JavidSumra@users.noreply.github.com> Date: Wed, 11 Dec 2024 12:46:56 +0530 Subject: [PATCH 02/21] Fix Infinite render on country code change (#9337) --- src/components/Form/FormFields/PhoneNumberFormField.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Form/FormFields/PhoneNumberFormField.tsx b/src/components/Form/FormFields/PhoneNumberFormField.tsx index 0fd6f914035..8b6566de8f7 100644 --- a/src/components/Form/FormFields/PhoneNumberFormField.tsx +++ b/src/components/Form/FormFields/PhoneNumberFormField.tsx @@ -105,7 +105,7 @@ const PhoneNumberFormField = React.forwardRef( } setCountry(phoneCodes[getCountryCode(field.value)!]); } - }, [setValue]); + }, [field.value]); return ( Date: Wed, 11 Dec 2024 14:33:31 +0530 Subject: [PATCH 03/21] Users Manage Test Fix (#9368) --- cypress/e2e/users_spec/UsersManage.cy.ts | 5 +++-- cypress/pageobject/Users/ManageUserPage.ts | 7 +++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/cypress/e2e/users_spec/UsersManage.cy.ts b/cypress/e2e/users_spec/UsersManage.cy.ts index 120eb551f57..39075b8b96f 100644 --- a/cypress/e2e/users_spec/UsersManage.cy.ts +++ b/cypress/e2e/users_spec/UsersManage.cy.ts @@ -34,6 +34,7 @@ describe("Manage User", () => { beforeEach(() => { cy.restoreLocalStorage(); + cy.viewport(1280, 720); cy.clearLocalStorage(/filters--.+/); cy.awaitUrl("/users"); }); @@ -233,7 +234,7 @@ describe("Manage User", () => { cy.wait(500); manageUserPage.verifyLinkedSkillsTabPage(); manageUserPage.selectSkillFromDropdown(linkedskill); - manageUserPage.clickAddSkillButton(); + manageUserPage.clickAddSkillButton(usernameforworkinghour); cy.wait(500); manageUserPage.assertSkillInAddedUserSkills(linkedskill); cy.wait(500); @@ -268,7 +269,7 @@ describe("Manage User", () => { manageUserPage.clickLinkedSkillTab(); manageUserPage.verifyLinkedSkillsTabPage(); manageUserPage.selectSkillFromDropdown(linkedskill); - manageUserPage.clickAddSkillButton(); + manageUserPage.clickAddSkillButton(usernameToLinkSkill); cy.verifyNotification("Skill added successfully"); cy.closeNotification(); manageUserPage.assertSkillInAddedUserSkills(linkedskill); diff --git a/cypress/pageobject/Users/ManageUserPage.ts b/cypress/pageobject/Users/ManageUserPage.ts index f5bbce7e95b..92e2008bfd8 100644 --- a/cypress/pageobject/Users/ManageUserPage.ts +++ b/cypress/pageobject/Users/ManageUserPage.ts @@ -127,6 +127,7 @@ export class ManageUserPage { } clearProfessionalInfo() { + cy.get("input[name='weekly_working_hours']").scrollIntoView(); cy.get("input[name='weekly_working_hours']").click().clear(); cy.get("input[name='video_connect_link']").click().clear(); } @@ -180,6 +181,7 @@ export class ManageUserPage { } typeInWeeklyWorkingHours(hours: string) { + cy.get("input[name='weekly_working_hours']").scrollIntoView(); cy.get("input[name='weekly_working_hours']").click().type(hours); } @@ -191,6 +193,7 @@ export class ManageUserPage { } verifyWorkingHours(expectedHours: string) { + cy.get("input[name='weekly_working_hours']").scrollIntoView(); cy.get("input[name='weekly_working_hours']").should("be.visible"); cy.get("input[name='weekly_working_hours']").should( "have.value", @@ -359,8 +362,8 @@ export class ManageUserPage { cy.get("[data-testid='user-delete-button']").click(); } - clickAddSkillButton() { - cy.intercept("GET", "**/api/v1/skill/**").as("getSkills"); + clickAddSkillButton(username: string) { + cy.intercept("GET", `**/api/v1/users/${username}/skill/**`).as("getSkills"); cy.get("#add-skill-button").click(); cy.wait("@getSkills").its("response.statusCode").should("eq", 200); } From e89530d39a98587d2f401ecd308b0dee79b51b4e Mon Sep 17 00:00:00 2001 From: Aditya Jindal Date: Wed, 11 Dec 2024 16:50:56 +0530 Subject: [PATCH 04/21] Upgrade cypress version (#9375) --- .github/workflows/cypress.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cypress.yaml b/.github/workflows/cypress.yaml index 3abf95cd4b0..6b731c8840b 100644 --- a/.github/workflows/cypress.yaml +++ b/.github/workflows/cypress.yaml @@ -68,7 +68,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: "20" + node-version: "22.11.0" - name: Install dependencies 📦 run: npm run install-all From 113ddddd5058a0bc8c160cd0dae1c6a59f9134e9 Mon Sep 17 00:00:00 2001 From: Anirban Biswas <139000437+ANIR1604@users.noreply.github.com> Date: Wed, 11 Dec 2024 19:26:32 +0530 Subject: [PATCH 05/21] Fix: [Clear Button is active when no input is selected in Dropdown] (#9264) --- src/components/Assets/AssetsList.tsx | 22 ++++++++--------- .../FacilitiesSelectDialogue.tsx | 2 +- src/components/Patient/ManagePatients.tsx | 24 ++++++++++--------- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/components/Assets/AssetsList.tsx b/src/components/Assets/AssetsList.tsx index 4212fae5d96..685d7dfa460 100644 --- a/src/components/Assets/AssetsList.tsx +++ b/src/components/Assets/AssetsList.tsx @@ -52,9 +52,7 @@ const AssetsList = () => { const [importAssetModalOpen, setImportAssetModalOpen] = useState(false); const assetsExist = assets.length > 0 && Object.keys(assets[0]).length > 0; const [showFacilityDialog, setShowFacilityDialog] = useState(false); - const [selectedFacility, setSelectedFacility] = useState({ - name: "", - }); + const [selectedFacility, setSelectedFacility] = useState(); const params = { limit: resultsPerPage, page: qParams.page, @@ -460,15 +458,11 @@ const AssetsList = () => {
)} - {typeof facility === "undefined" && ( + {facility == null && ( setFacility(e)} - selectedFacility={ - facility ?? { - name: "", - } - } + selectedFacility={selectedFacility} handleOk={() => { return undefined; }} @@ -497,10 +491,16 @@ const AssetsList = () => { show={showFacilityDialog} setSelected={(e) => setSelectedFacility(e)} selectedFacility={selectedFacility} - handleOk={() => navigate(`facility/${selectedFacility.id}/assets/new`)} + handleOk={() => { + if (selectedFacility) { + navigate(`facility/${selectedFacility.id}/assets/new`); + } else { + Notification.Warn({ msg: "No facility selected" }); + } + }} handleCancel={() => { setShowFacilityDialog(false); - setSelectedFacility({ name: "" }); + setSelectedFacility(undefined); }} /> diff --git a/src/components/ExternalResult/FacilitiesSelectDialogue.tsx b/src/components/ExternalResult/FacilitiesSelectDialogue.tsx index 66e290c069d..9e8bb4fbf06 100644 --- a/src/components/ExternalResult/FacilitiesSelectDialogue.tsx +++ b/src/components/ExternalResult/FacilitiesSelectDialogue.tsx @@ -11,7 +11,7 @@ interface Props { show: boolean; handleOk: () => void; handleCancel: () => void; - selectedFacility: FacilityModel; + selectedFacility: FacilityModel | null | undefined; setSelected: (e: any) => void; } diff --git a/src/components/Patient/ManagePatients.tsx b/src/components/Patient/ManagePatients.tsx index 65fc0e73933..25a1f9166ed 100644 --- a/src/components/Patient/ManagePatients.tsx +++ b/src/components/Patient/ManagePatients.tsx @@ -100,9 +100,7 @@ export const PatientManager = () => { "emergency_phone_number", ], }); - const [selectedFacility, setSelectedFacility] = useState({ - name: "", - }); + const [selectedFacility, setSelectedFacility] = useState(); const authUser = useAuthUser(); const [diagnoses, setDiagnoses] = useState([]); const [showDialog, setShowDialog] = useState<"create" | "list-discharged">(); @@ -976,18 +974,22 @@ export const PatientManager = () => { setSelected={(e) => setSelectedFacility(e)} selectedFacility={selectedFacility} handleOk={() => { - switch (showDialog) { - case "create": - navigate(`facility/${selectedFacility.id}/patient`); - break; - case "list-discharged": - navigate(`facility/${selectedFacility.id}/discharged-patients`); - break; + if (selectedFacility) { + switch (showDialog) { + case "create": + navigate(`facility/${selectedFacility.id}/patient`); + break; + case "list-discharged": + navigate(`facility/${selectedFacility.id}/discharged-patients`); + break; + } + } else { + Notification.Error({ msg: "No facility selected" }); } }} handleCancel={() => { setShowDialog(undefined); - setSelectedFacility({ name: "" }); + setSelectedFacility(undefined); }} /> From 3ba5dc6a7030fe6e81a164078483eb3f251e7601 Mon Sep 17 00:00:00 2001 From: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> Date: Wed, 11 Dec 2024 21:25:52 +0530 Subject: [PATCH 06/21] Fixed the user management page cypress issue (#9384) --- cypress/e2e/users_spec/UsersManage.cy.ts | 1 + cypress/pageobject/Users/ManageUserPage.ts | 12 ++++-------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/cypress/e2e/users_spec/UsersManage.cy.ts b/cypress/e2e/users_spec/UsersManage.cy.ts index 39075b8b96f..c7d237efb43 100644 --- a/cypress/e2e/users_spec/UsersManage.cy.ts +++ b/cypress/e2e/users_spec/UsersManage.cy.ts @@ -305,6 +305,7 @@ describe("Manage User", () => { manageUserPage.clickSubmit(); // verify the data is reflected in the page manageUserPage.verifyWorkingHours(workinghour); + manageUserPage.navigateToProfile(); manageUserPage.verifyProfileWorkingHours(workinghour); }); diff --git a/cypress/pageobject/Users/ManageUserPage.ts b/cypress/pageobject/Users/ManageUserPage.ts index 92e2008bfd8..24c056a70eb 100644 --- a/cypress/pageobject/Users/ManageUserPage.ts +++ b/cypress/pageobject/Users/ManageUserPage.ts @@ -193,19 +193,15 @@ export class ManageUserPage { } verifyWorkingHours(expectedHours: string) { - cy.get("input[name='weekly_working_hours']").scrollIntoView(); - cy.get("input[name='weekly_working_hours']").should("be.visible"); - cy.get("input[name='weekly_working_hours']").should( - "have.value", + cy.verifyContentPresence("#view-average_weekly_working_hours", [ expectedHours, - ); + ] as string[]); } verifyProfileWorkingHours(expectedHours: string) { - cy.get("#view-average_weekly_working_hours").should( - "contain.text", + cy.verifyContentPresence("#averageworkinghour-profile-details", [ expectedHours, - ); + ] as string[]); } navigateToManageUser() { From f70b3ad0fef68ecee8b89601ae1b42371bc5e8e1 Mon Sep 17 00:00:00 2001 From: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> Date: Wed, 11 Dec 2024 22:24:41 +0530 Subject: [PATCH 07/21] Fixed Flaky test in the user advance filters (#9385) --- cypress/e2e/users_spec/UsersHomepage.cy.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cypress/e2e/users_spec/UsersHomepage.cy.ts b/cypress/e2e/users_spec/UsersHomepage.cy.ts index acc1639e003..a82b718047d 100644 --- a/cypress/e2e/users_spec/UsersHomepage.cy.ts +++ b/cypress/e2e/users_spec/UsersHomepage.cy.ts @@ -8,15 +8,15 @@ describe("User Homepage", () => { const userPage = new UserPage(); const loginPage = new LoginPage(); const currentuser = "devdistrictadmin"; - const firstName = "Dummy"; - const lastName = "Nurse"; + const firstName = "Dev"; + const lastName = "Staff"; const role = "Nurse"; const state = "Kerala"; const district = "Ernakulam"; - const phoneNumber = "8878825662"; - const altPhoneNumber = "8878825662"; + const phoneNumber = "9876543219"; + const altPhoneNumber = "9876543219"; const homeFacility = "Dummy Facility 40"; - const nurseUserName = "dummynurse1"; + const nurseUserName = "devstaff2"; const doctorUserName = "dev-doctor2"; before(() => { From b6df9a1af1c3320854a14155c352ad8781b83d03 Mon Sep 17 00:00:00 2001 From: Shivank Kacker Date: Wed, 11 Dec 2024 23:03:41 +0530 Subject: [PATCH 08/21] Scribe Enhancements support PR (#9265) --- public/locale/en.json | 1 + src/style/CAREUI.css | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/public/locale/en.json b/public/locale/en.json index 9f0bc5ecf12..a37d6b4b115 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -1418,6 +1418,7 @@ "total_patients": "Total Patients", "total_staff": "Total Staff", "total_users": "Total Users", + "transcribe_again": "Transcribe Again", "transcript_edit_info": "You can update this if we made an error", "transcript_information": "This is what we heard", "transfer_allowed": "Transfer Allowed", diff --git a/src/style/CAREUI.css b/src/style/CAREUI.css index 2acc88a2b05..e65c2c5554e 100644 --- a/src/style/CAREUI.css +++ b/src/style/CAREUI.css @@ -177,4 +177,9 @@ button.button-alert-ghost { @apply enabled:hover:bg-alert-100 } } hr { @apply border border-secondary-300 +} +.plain-audio::-webkit-media-controls-enclosure { + border-radius: 0; + background: transparent; + padding: 0px; } \ No newline at end of file From 27b7228aa9554add6bf683e977d4c04455712746 Mon Sep 17 00:00:00 2001 From: Pooranjoy Bhattacharya Date: Wed, 11 Dec 2024 23:12:23 +0530 Subject: [PATCH 09/21] Bug-Fix: Patient's Age parsing discrepancy during XLS export in Sample Management System (#9247) --- src/components/Patient/SampleViewAdmin.tsx | 41 +++++++++++++--------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/components/Patient/SampleViewAdmin.tsx b/src/components/Patient/SampleViewAdmin.tsx index dcb98d9f28c..ff269c90358 100644 --- a/src/components/Patient/SampleViewAdmin.tsx +++ b/src/components/Patient/SampleViewAdmin.tsx @@ -117,22 +117,31 @@ export default function SampleViewAdmin() { }); }; - const parseExportData = (data: string) => - data - .trim() - .split("\n") - .map((row: string) => - row - .trim() - .split(",") - .map((field: string) => - new Date(field).toString() === "Invalid Date" - ? field - : formatDateTime(field), - ) - .join(","), - ) - .join("\n"); + const parseExportData = (data: string) => { + const [header, ...rows] = data.trim().split("\n"); + const headerColumns = header.split(",").map((col) => col.trim()); + + return [ + header, + ...rows.map((row) => { + const columns = row.split(",").map((field, index) => { + const header = headerColumns[index]; + + if (header === "Patient Age") { + return field.trim(); + } + + if (["Date of Sample", "Date of Result"].includes(header)) { + const formattedDate = formatDateTime(field.trim()); + return formattedDate === "Invalid Date" ? "" : formattedDate; + } + return field.includes(",") ? `"${field.trim()}"` : field.trim(); + }); + + return columns.join(","); + }), + ].join("\n"); + }; let sampleList: any[] = []; if (sampeleData?.count) { From 981a281103aec9d32c827ba1bfb4f1c441f4ae2b Mon Sep 17 00:00:00 2001 From: Jacob John Jeevan <40040905+Jacobjeevan@users.noreply.github.com> Date: Wed, 11 Dec 2024 23:13:36 +0530 Subject: [PATCH 10/21] Facility bed capacity verification test (#9145) --- .../e2e/facility_spec/FacilityCreation.cy.ts | 156 ++++++++++++------ .../e2e/facility_spec/FacilityHomepage.cy.ts | 59 +++++++ .../PatientConsultationCreation.cy.ts | 8 +- .../patient_spec/PatientRegistration.cy.ts | 75 +++++---- .../pageobject/Facility/FacilityCreation.ts | 148 ++++++++++++++++- cypress/pageobject/Facility/FacilityHome.ts | 20 ++- .../pageobject/Facility/FacilityLocation.ts | 2 +- cypress/pageobject/Facility/FacilityManage.ts | 8 + cypress/pageobject/Patient/PatientCreation.ts | 105 ++++++++++++ cypress/pageobject/Patient/PatientHome.ts | 4 + .../Patient/PatientTreatmentPlan.ts | 2 +- src/components/Facility/FacilityCard.tsx | 2 +- src/components/Patient/PatientHome.tsx | 6 +- 13 files changed, 489 insertions(+), 106 deletions(-) diff --git a/cypress/e2e/facility_spec/FacilityCreation.cy.ts b/cypress/e2e/facility_spec/FacilityCreation.cy.ts index 78ce17d8b9e..f644c9829d3 100644 --- a/cypress/e2e/facility_spec/FacilityCreation.cy.ts +++ b/cypress/e2e/facility_spec/FacilityCreation.cy.ts @@ -1,6 +1,8 @@ import { advanceFilters } from "pageobject/utils/advanceFilterHelpers"; -import FacilityPage from "../../pageobject/Facility/FacilityCreation"; +import FacilityPage, { + FacilityData, +} from "../../pageobject/Facility/FacilityCreation"; import FacilityHome from "../../pageobject/Facility/FacilityHome"; import LoginPage from "../../pageobject/Login/LoginPage"; import ManageUserPage from "../../pageobject/Users/ManageUserPage"; @@ -59,6 +61,61 @@ describe("Facility Creation", () => { ]; const triageErrorMessage = ["This field is required"]; const facilityType = "Primary Health Centres"; + const testFacilityData: FacilityData = { + basic: { + name: facilityName, + type: facilityType, + features: facilityFeature, + address: facilityAddress, + phoneNumber: facilityNumber, + location: "Kochi, Kerala", + }, + location: { + pincode: "682001", + state: "Kerala", + district: "Ernakulam", + localBody: "Aluva", + ward: "4", + }, + oxygen: { + capacity: oxygenCapacity, + expected: oxygenExpected, + bType: { + capacity: oxygenCapacity, + expected: oxygenExpected, + }, + cType: { + capacity: oxygenCapacity, + expected: oxygenExpected, + }, + dType: { + capacity: oxygenCapacity, + expected: oxygenExpected, + }, + }, + beds: [ + { + type: "Oxygen Supported Bed", + totalCapacity: bedCapacity, + occupied: bedOccupancy, + }, + { + type: "Ordinary Bed", + totalCapacity: bedCapacity, + occupied: bedOccupancy, + }, + ], + doctors: [ + { + specialization: "General Medicine", + count: doctorCapacity, + }, + { + specialization: "Pulmonology", + count: doctorCapacity, + }, + ], + }; before(() => { loginPage.loginByRole("districtAdmin"); @@ -122,32 +179,12 @@ describe("Facility Creation", () => { facilityPage.visitCreateFacilityPage(); facilityPage.submitForm(); cy.verifyErrorMessages(facilityErrorMessage); - facilityPage.fillFacilityName(facilityName); - facilityPage.selectFacilityType(facilityType); - facilityPage.clickfacilityfeatureoption(); - facilityFeature.forEach((featureText) => { - cy.get("[role='option']").contains(featureText).click(); - }); - facilityPage.clickfacilityfeatureoption(); - facilityPage.fillPincode("682001"); - facilityPage.selectStateOnPincode("Kerala"); - facilityPage.selectDistrictOnPincode("Ernakulam"); - facilityPage.selectLocalBody("Aluva"); - facilityPage.selectWard("4"); - facilityPage.fillAddress(facilityAddress); - facilityPage.fillPhoneNumber(facilityNumber); - facilityPage.fillOxygenCapacity(oxygenCapacity); - facilityPage.fillExpectedOxygenRequirement(oxygenExpected); - facilityPage.fillBTypeCylinderCapacity(oxygenCapacity); - facilityPage.fillExpectedBTypeCylinderRequirement(oxygenExpected); - facilityPage.fillCTypeCylinderCapacity(oxygenCapacity); - facilityPage.fillExpectedCTypeCylinderRequirement(oxygenExpected); - facilityPage.fillDTypeCylinderCapacity(oxygenCapacity); - facilityPage.fillExpectedDTypeCylinderRequirement(oxygenExpected); - facilityPage.selectLocation("Kochi, Kerala"); + facilityPage.fillBasicDetails(testFacilityData.basic); + facilityPage.fillLocationDetails(testFacilityData.location); + facilityPage.fillOxygenDetails(testFacilityData.oxygen); facilityPage.submitForm(); cy.closeNotification(); - // create multiple bed capacity and verify card reflection + // add the bed capacity facilityPage.selectBedType("Oxygen Supported Bed"); facilityPage.fillTotalCapacity(bedCapacity); facilityPage.fillCurrentlyOccupied(bedOccupancy); @@ -210,27 +247,32 @@ describe("Facility Creation", () => { }); it("Create a new facility with single bed and doctor capacity", () => { - facilityPage.visitCreateFacilityPage(); - facilityPage.fillFacilityName(facilityName); - facilityPage.selectFacilityType(facilityType); - facilityPage.fillPincode("682001"); - facilityPage.selectStateOnPincode("Kerala"); - facilityPage.selectDistrictOnPincode("Ernakulam"); - facilityPage.selectLocalBody("Aluva"); - facilityPage.selectWard("4"); - facilityPage.fillAddress(facilityAddress); - facilityPage.fillPhoneNumber(facilityNumber); - facilityPage.submitForm(); - // add the bed capacity - facilityPage.selectBedType("Oxygen Supported Bed"); - facilityPage.fillTotalCapacity(oxygenCapacity); - facilityPage.fillCurrentlyOccupied(oxygenExpected); - facilityPage.saveAndExitBedCapacityForm(); - // add the doctor capacity - facilityPage.selectAreaOfSpecialization("General Medicine"); - facilityPage.fillDoctorCount(doctorCapacity); - facilityPage.saveAndExitDoctorForm(); - facilityPage.verifyfacilitynewurl(); + const singleCapacityData = { + ...testFacilityData, + // Remove features, location, and oxygen that aren't used in this test + basic: { + ...testFacilityData.basic, + features: undefined, + location: undefined, + }, + oxygen: undefined, + // Override with single bed capacity + beds: [ + { + type: "Oxygen Supported Bed", + totalCapacity: oxygenCapacity, + occupied: oxygenExpected, + }, + ], + // Override with single doctor capacity + doctors: [ + { + specialization: "General Medicine", + count: doctorCapacity, + }, + ], + }; + facilityPage.createNewFacility(singleCapacityData); // verify the created facility details facilityPage.getFacilityName().contains(facilityName).should("be.visible"); facilityPage @@ -254,16 +296,20 @@ describe("Facility Creation", () => { }); it("Create a new facility with no bed and doctor capacity", () => { + const noCapacityData = { + ...testFacilityData, + basic: { + ...testFacilityData.basic, + features: undefined, + location: undefined, + }, + oxygen: undefined, + beds: [], + doctors: [], + }; facilityPage.visitCreateFacilityPage(); - facilityPage.fillFacilityName(facilityName); - facilityPage.selectFacilityType(facilityType); - facilityPage.fillPincode("682001"); - facilityPage.selectStateOnPincode("Kerala"); - facilityPage.selectDistrictOnPincode("Ernakulam"); - facilityPage.selectLocalBody("Aluva"); - facilityPage.selectWard("4"); - facilityPage.fillAddress(facilityAddress); - facilityPage.fillPhoneNumber(facilityNumber); + facilityPage.fillBasicDetails(noCapacityData.basic); + facilityPage.fillLocationDetails(noCapacityData.location); facilityPage.submitForm(); // add no bed capacity and verify form error message facilityPage.isVisibleselectBedType(); diff --git a/cypress/e2e/facility_spec/FacilityHomepage.cy.ts b/cypress/e2e/facility_spec/FacilityHomepage.cy.ts index 6f01baac714..680ce6fa2ce 100644 --- a/cypress/e2e/facility_spec/FacilityHomepage.cy.ts +++ b/cypress/e2e/facility_spec/FacilityHomepage.cy.ts @@ -1,4 +1,7 @@ // FacilityCreation +import FacilityLocation from "pageobject/Facility/FacilityLocation"; +import { PatientPage } from "pageobject/Patient/PatientCreation"; +import PatientPredefined from "pageobject/Patient/PatientPredefined"; import { pageNavigation } from "pageobject/utils/paginationHelpers"; import FacilityPage from "../../pageobject/Facility/FacilityCreation"; @@ -14,6 +17,9 @@ describe("Facility Homepage Function", () => { const facilityNotify = new FacilityNotify(); const facilityPage = new FacilityPage(); const manageUserPage = new ManageUserPage(); + const patientPredefined = new PatientPredefined(); + const patientPage = new PatientPage(); + const facilityLocation = new FacilityLocation(); const facilitiesAlias = "downloadFacilitiesCSV"; const doctorsAlias = "downloadDoctorsCSV"; const triagesAlias = "downloadTriagesCSV"; @@ -25,6 +31,9 @@ describe("Facility Homepage Function", () => { const facilityType = "Private Hospital"; const notificationErrorMsg = "Message cannot be empty"; const notificationMessage = "Test Notification"; + const facilityWithNoAvailableBeds = "Dummy Facility 12"; + const locationName = "Test-location"; + const locationType = "WARD"; before(() => { loginPage.loginByRole("districtAdmin"); @@ -32,6 +41,7 @@ describe("Facility Homepage Function", () => { }); beforeEach(() => { + cy.viewport(1280, 720); cy.restoreLocalStorage(); cy.clearLocalStorage(/filters--.+/); cy.awaitUrl("/facility"); @@ -199,6 +209,55 @@ describe("Facility Homepage Function", () => { facilityNotify.closeNotificationSlide(); loginPage.ensureLoggedIn(); loginPage.clickSignOutBtn(); + loginPage.loginManuallyAsDistrictAdmin(); + loginPage.ensureLoggedIn(); + }); + + it("Verify the bed capacity badge reflection", () => { + facilityHome.typeFacilitySearch(facilityWithNoAvailableBeds); + facilityHome.assertFacilityInCard(facilityWithNoAvailableBeds); + cy.url().then((url) => { + const facilityUrl = url.toString(); + facilityHome.verifyOccupancyBadgeVisibility(); + facilityHome.assertFacilityBadgeContent("0", "0"); + + // create a new patient in the facility + cy.visit("/patients"); + patientPage.createPatient(); + patientPage.selectFacility(facilityWithNoAvailableBeds); + patientPredefined.createPatient(); + patientPage.patientformvisibility(); + patientPage.clickCreatePatient(); + patientPage.verifyPatientIsCreated(); + // navigate to facility page and verify the occupancy badge + cy.visit(facilityUrl); + facilityHome.verifyOccupancyBadgeVisibility(); + facilityHome.assertFacilityBadgeContent("1", "0"); + facilityHome.assertFacilityBadgeBackgroundColor("rgb(239, 68, 68)"); + // create a new location and add a bed to the facility + facilityLocation.navigateToFacilityLocationManagement( + facilityWithNoAvailableBeds, + ); + // create new location and add a bed to the facility + facilityLocation.clickAddNewLocationButton(); + facilityLocation.fillLocationDetails( + locationName, + undefined, + locationType, + undefined, + ); + facilityLocation.clickAddLocationButton(); + facilityLocation.verifyAddLocationSuccessfulMesssage(); + facilityLocation.clickManageBedButton(locationName); + facilityLocation.clickAddBedButton(); + facilityLocation.fillBedForm("Bed 1", "Test Description", "Regular", 2); + facilityLocation.clickSubmitBedsButton(); + + // verify the occupancy badge reflection + cy.visit(facilityUrl); + facilityHome.verifyOccupancyBadgeVisibility(); + facilityHome.assertFacilityBadgeContent("1", "2"); + }); }); afterEach(() => { diff --git a/cypress/e2e/patient_spec/PatientConsultationCreation.cy.ts b/cypress/e2e/patient_spec/PatientConsultationCreation.cy.ts index 4191d63b3e2..a257d127942 100644 --- a/cypress/e2e/patient_spec/PatientConsultationCreation.cy.ts +++ b/cypress/e2e/patient_spec/PatientConsultationCreation.cy.ts @@ -90,7 +90,7 @@ describe("Patient Consultation in multiple combination", () => { patientTreatmentPlan.typeTreatmentPlan(patientTreatment); patientTreatmentPlan.typePatientGeneralInstruction(generalInstruction); patientTreatmentPlan.typeSpecialInstruction(specialInstruction); - patientTreatmentPlan.fillTreatingPhysican(doctorName); + patientTreatmentPlan.fillTreatingPhysician(doctorName); cy.clickSubmitButton("Create Consultation"); // the above submit should fail as IP number is missing patientConsultationPage.typePatientNumber(patientIpNumber); @@ -254,7 +254,7 @@ describe("Patient Consultation in multiple combination", () => { patientInvestigation.selectInvestigationFrequency("6"); // Add advice and treating physican patientTreatmentPlan.typePatientGeneralInstruction(generalInstruction); - patientTreatmentPlan.fillTreatingPhysican(doctorName); + patientTreatmentPlan.fillTreatingPhysician(doctorName); // add review after and add action patientTreatmentPlan.selectReviewAfter("15 mins"); patientTreatmentPlan.selectAction("Specialist Required"); @@ -311,7 +311,7 @@ describe("Patient Consultation in multiple combination", () => { // no investigation patientTreatmentPlan.typePatientGeneralInstruction(generalInstruction); // no review after and no action - patientTreatmentPlan.fillTreatingPhysican(doctorName); + patientTreatmentPlan.fillTreatingPhysician(doctorName); cy.clickSubmitButton("Create Consultation"); cy.verifyNotification("Patient discharged successfully"); // verify the Discharge Reason, Diagnosis, treatment physican @@ -362,7 +362,7 @@ describe("Patient Consultation in multiple combination", () => { patientConsultationPage.selectPatientPrincipalDiagnosis(diagnosis4); // no investigation for the patient patientTreatmentPlan.typePatientGeneralInstruction(generalInstruction); - patientTreatmentPlan.fillTreatingPhysican(doctorName); + patientTreatmentPlan.fillTreatingPhysician(doctorName); // no review after and no action cy.clickSubmitButton("Create Consultation"); // Create a shifting request diff --git a/cypress/e2e/patient_spec/PatientRegistration.cy.ts b/cypress/e2e/patient_spec/PatientRegistration.cy.ts index a7c869401cd..b11d0f8f585 100644 --- a/cypress/e2e/patient_spec/PatientRegistration.cy.ts +++ b/cypress/e2e/patient_spec/PatientRegistration.cy.ts @@ -1,6 +1,8 @@ -import FacilityPage from "../../pageobject/Facility/FacilityCreation"; import LoginPage from "../../pageobject/Login/LoginPage"; -import { PatientPage } from "../../pageobject/Patient/PatientCreation"; +import { + PatientData, + PatientPage, +} from "../../pageobject/Patient/PatientCreation"; import PatientInsurance from "../../pageobject/Patient/PatientInsurance"; import PatientMedicalHistory from "../../pageobject/Patient/PatientMedicalHistory"; import PatientTransfer from "../../pageobject/Patient/PatientTransfer"; @@ -30,7 +32,6 @@ const getRelativeDateString = (deltaDays = 0) => { describe("Patient Creation with consultation", () => { const loginPage = new LoginPage(); const patientPage = new PatientPage(); - const facilityPage = new FacilityPage(); const patientTransfer = new PatientTransfer(); const patientInsurance = new PatientInsurance(); const patientMedicalHistory = new PatientMedicalHistory(); @@ -68,6 +69,38 @@ describe("Patient Creation with consultation", () => { const patientTransferFacility = "Dummy Shifting Center"; const patientTransferName = "Dummy Patient Twelve"; const patientOccupation = "Student"; + const newPatientData: PatientData = { + facility: patientFacility, + phoneNumber: phone_number, + isEmergencyNumber: true, + age: age.toString(), + name: patientOneName, + gender: patientOneGender, + address: patientOneAddress, + pincode: patientOnePincode, + state: patientOneState, + district: patientOneDistrict, + localBody: patientOneLocalbody, + ward: patientOneWard, + occupation: patientOccupation, + socioeconomicStatus: "MIDDLE_CLASS", + domesticHealthcareSupport: "FAMILY_MEMBER", + medicalHistory: { + presentHealth: patientOnePresentHealth, + ongoingMedication: patientOneOngoingMedication, + conditions: [ + { index: 2, condition: "Diabetes" }, + { index: 3, condition: "Heart Disease" }, + { index: 4, condition: "HyperTension" }, + { index: 5, condition: "Kidney Diseases" }, + { index: 6, condition: "Lung Diseases/Asthma" }, + { index: 7, condition: "Cancer" }, + { index: 8, condition: "Other" }, + ], + allergies: patientOneAllergies, + }, + bloodGroup: patientOneBloodGroup, + }; before(() => { loginPage.loginByRole("districtAdmin"); @@ -81,41 +114,7 @@ describe("Patient Creation with consultation", () => { }); it("Create a new patient with all field in registration form and no consultation", () => { - // patient details with all the available fields except covid - patientPage.createPatient(); - patientPage.selectFacility(patientFacility); - patientPage.patientformvisibility(); - // Patient Details page - patientPage.typePatientPhoneNumber(phone_number); - patientPage.checkPhoneNumberIsEmergencyNumber(); - patientPage.typePatientAge(age.toString()); - patientPage.typePatientName(patientOneName); - patientPage.selectPatientGender(patientOneGender); - patientPage.typePatientAddress(patientOneAddress); - facilityPage.fillPincode(patientOnePincode); - facilityPage.selectStateOnPincode(patientOneState); - facilityPage.selectDistrictOnPincode(patientOneDistrict); - facilityPage.selectLocalBody(patientOneLocalbody); - facilityPage.selectWard(patientOneWard); - patientPage.selectPatientOccupation(patientOccupation); - patientPage.selectSocioeconomicStatus("MIDDLE_CLASS"); - patientPage.selectDomesticHealthcareSupport("FAMILY_MEMBER"); - // Patient Medical History - patientMedicalHistory.typePatientPresentHealth(patientOnePresentHealth); - patientMedicalHistory.typePatientOngoingMedication( - patientOneOngoingMedication, - ); - patientMedicalHistory.typeMedicalHistory(2, "Diabetes"); - patientMedicalHistory.typeMedicalHistory(3, "Heart Disease"); - patientMedicalHistory.typeMedicalHistory(4, "HyperTension"); - patientMedicalHistory.typeMedicalHistory(5, "Kidney Diseases"); - patientMedicalHistory.typeMedicalHistory(6, "Lung Diseases/Asthma"); - patientMedicalHistory.typeMedicalHistory(7, "Cancer"); - patientMedicalHistory.typeMedicalHistory(8, "Other"); - patientMedicalHistory.typePatientAllergies(patientOneAllergies); - patientPage.selectPatientBloodGroup(patientOneBloodGroup); - patientPage.clickCreatePatient(); - patientPage.verifyPatientIsCreated(); + patientPage.createPatientWithData(newPatientData); // Verify the patient details patientPage.clickCancelButton(); cy.wait(3000); diff --git a/cypress/pageobject/Facility/FacilityCreation.ts b/cypress/pageobject/Facility/FacilityCreation.ts index 4c064956fcc..e59dfef09f3 100644 --- a/cypress/pageobject/Facility/FacilityCreation.ts +++ b/cypress/pageobject/Facility/FacilityCreation.ts @@ -1,5 +1,48 @@ import { advanceFilters } from "pageobject/utils/advanceFilterHelpers"; +export interface FacilityData { + basic: { + name: string; + type: string; + features?: string[]; + address: string; + phoneNumber: string; + location?: string; + }; + location: { + pincode: string; + state: string; + district: string; + localBody: string; + ward: string; + }; + oxygen?: { + capacity: string; + expected: string; + bType?: { + capacity: string; + expected: string; + }; + cType?: { + capacity: string; + expected: string; + }; + dType?: { + capacity: string; + expected: string; + }; + }; + beds?: Array<{ + type: string; + totalCapacity: string; + occupied: string; + }>; + doctors?: Array<{ + specialization: string; + count: string; + }>; +} + class FacilityPage { visitCreateFacilityPage() { cy.intercept("GET", "**/facility/create").as("getCreateFacilities"); @@ -405,9 +448,8 @@ class FacilityPage { } selectDistrictOnPincode(districtName: string) { - this.getDistrictElement() - .scrollIntoView() - .wait(2000) + this.getDistrictElement().as("district").scrollIntoView().wait(2000); + cy.get("@district") .should("be.visible") .then(($element) => { const text = $element.text(); @@ -457,6 +499,106 @@ class FacilityPage { clickSetMinimumQuantity() { cy.get("#set-minimum-quantity").click(); } + + createNewFacility(data: FacilityData) { + this.visitCreateFacilityPage(); + + // Fill basic details + this.fillBasicDetails(data.basic); + + // Fill location details + this.fillLocationDetails(data.location); + + // Fill oxygen details if provided + if (data.oxygen) { + this.fillOxygenDetails(data.oxygen); + } + + this.submitForm(); + cy.closeNotification(); + + // Add bed capacity if provided + if (data.beds) { + this.addBedCapacities(data.beds); + } + + // Add doctor capacity if provided + if (data.doctors) { + this.addDoctorCapacities(data.doctors); + } + + this.verifyfacilitynewurl(); + return this; + } + + fillBasicDetails(basic: FacilityData["basic"]) { + this.fillFacilityName(basic.name); + this.selectFacilityType(basic.type); + + if (basic.features?.length) { + this.clickfacilityfeatureoption(); + basic.features.forEach((feature) => { + cy.get("[role='option']").contains(feature).click(); + }); + this.clickfacilityfeatureoption(); + } + + this.fillAddress(basic.address); + this.fillPhoneNumber(basic.phoneNumber); + + if (basic.location) { + this.selectLocation(basic.location); + } + } + + fillLocationDetails(location: FacilityData["location"]) { + this.fillPincode(location.pincode); + this.selectStateOnPincode(location.state); + this.selectDistrictOnPincode(location.district); + this.selectLocalBody(location.localBody); + this.selectWard(location.ward); + } + + fillOxygenDetails(oxygen: NonNullable) { + this.fillOxygenCapacity(oxygen.capacity); + this.fillExpectedOxygenRequirement(oxygen.expected); + + if (oxygen.bType) { + this.fillBTypeCylinderCapacity(oxygen.bType.capacity); + this.fillExpectedBTypeCylinderRequirement(oxygen.bType.expected); + } + + if (oxygen.cType) { + this.fillCTypeCylinderCapacity(oxygen.cType.capacity); + this.fillExpectedCTypeCylinderRequirement(oxygen.cType.expected); + } + + if (oxygen.dType) { + this.fillDTypeCylinderCapacity(oxygen.dType.capacity); + this.fillExpectedDTypeCylinderRequirement(oxygen.dType.expected); + } + } + + addBedCapacities(beds: NonNullable) { + beds.forEach((bed) => { + this.selectBedType(bed.type); + this.fillTotalCapacity(bed.totalCapacity); + this.fillCurrentlyOccupied(bed.occupied); + this.clickbedcapcityaddmore(); + cy.closeNotification(); + }); + this.clickcancelbutton(); + } + + addDoctorCapacities(doctors: NonNullable) { + doctors.forEach((doctor) => { + this.selectAreaOfSpecialization(doctor.specialization); + this.fillDoctorCount(doctor.count); + this.clickdoctorcapacityaddmore(); + cy.closeNotification(); + }); + this.clickcancelbutton(); + } } export default FacilityPage; diff --git a/cypress/pageobject/Facility/FacilityHome.ts b/cypress/pageobject/Facility/FacilityHome.ts index fe8585b48be..bbf5945453e 100644 --- a/cypress/pageobject/Facility/FacilityHome.ts +++ b/cypress/pageobject/Facility/FacilityHome.ts @@ -50,8 +50,9 @@ class FacilityHome { } clickFacilityNotifyButton() { - cy.get("#facility-notify", { timeout: 10000 }).should("be.visible"); - cy.get("#facility-notify").focus().click(); + cy.get("#facility-notify").as("facilityNotify"); + cy.get("@facilityNotify", { timeout: 10000 }).should("be.visible"); + cy.get("@facilityNotify").first().click(); } clickLiveMonitorButton() { @@ -114,6 +115,21 @@ class FacilityHome { const encodedText = encodeURIComponent(searchText).replace(/%20/g, "+"); this.getURL().should("include", `search=${encodedText}`); } + + assertFacilityBadgeContent(occupied: string, total: string) { + cy.get('[data-test-id="occupancy-badge-text"]').should( + "contain.text", + `Occupancy: ${occupied} / ${total}`, + ); + } + + assertFacilityBadgeBackgroundColor(color: string) { + cy.get('[data-test-id="occupancy-badge"]').should( + "have.css", + "background-color", + color, + ); + } } export default FacilityHome; diff --git a/cypress/pageobject/Facility/FacilityLocation.ts b/cypress/pageobject/Facility/FacilityLocation.ts index 9cb23f9fba0..2932dfb8dcd 100644 --- a/cypress/pageobject/Facility/FacilityLocation.ts +++ b/cypress/pageobject/Facility/FacilityLocation.ts @@ -50,7 +50,7 @@ class FacilityLocation { } clickAddNewLocationButton() { - cy.get("#add-new-location").click(); + cy.get("#add-new-location").click({ force: true }); } typeLocationName(locationName: string) { diff --git a/cypress/pageobject/Facility/FacilityManage.ts b/cypress/pageobject/Facility/FacilityManage.ts index 9a32a5be36f..e7eecddab3c 100644 --- a/cypress/pageobject/Facility/FacilityManage.ts +++ b/cypress/pageobject/Facility/FacilityManage.ts @@ -99,5 +99,13 @@ class FacilityManage { cy.get("#facility-add-bedtype").scrollIntoView(); cy.get("#facility-add-bedtype").click(); } + + visitViewPatients() { + cy.intercept("GET", "**/api/v1/facility/**").as("getFacilityPatients"); + cy.get("#view-patient-facility-list").scrollIntoView().click(); + cy.wait("@getFacilityPatients") + .its("response.statusCode") + .should("eq", 200); + } } export default FacilityManage; diff --git a/cypress/pageobject/Patient/PatientCreation.ts b/cypress/pageobject/Patient/PatientCreation.ts index febf31b33b5..635aac3c4d2 100644 --- a/cypress/pageobject/Patient/PatientCreation.ts +++ b/cypress/pageobject/Patient/PatientCreation.ts @@ -1,6 +1,36 @@ // PatientPage.ts +import FacilityPage from "pageobject/Facility/FacilityCreation"; + +import PatientMedicalHistory from "./PatientMedicalHistory"; let patient_url = ""; +const facilityPage = new FacilityPage(); +const patientMedicalHistory = new PatientMedicalHistory(); + +export interface PatientData { + facility: string; + phoneNumber: string; + isEmergencyNumber?: boolean; + age: string | number; + name: string; + gender: string; + address: string; + pincode: string; + state: string; + district: string; + localBody: string; + ward: string; + occupation?: string; + socioeconomicStatus?: string; + domesticHealthcareSupport?: string; + medicalHistory?: { + presentHealth?: string; + ongoingMedication?: string; + conditions?: { index: number; condition: string }[]; + allergies?: string; + }; + bloodGroup?: string; +} export class PatientPage { createPatient() { @@ -22,6 +52,16 @@ export class PatientPage { .contains(patientName); } + visitPatientWithNoConsultation(patientName: string) { + cy.get("#name").click().type(patientName); + cy.intercept("GET", "**/api/v1/patient/**").as("getPatient"); + cy.get("#patient-name-list").contains(patientName).click(); + cy.wait("@getPatient").its("response.statusCode").should("eq", 200); + cy.get("#patient-name").should("be.visible").contains(patientName); + cy.get("#create-consultation").should("be.visible"); + this.clickCreateConsultationOnPatientPageWithNoConsultation(); + } + selectFacility(facilityName: string) { cy.typeAndSelectOption("input[name='facilities']", facilityName); cy.clickSubmitButton("Select"); @@ -154,6 +194,10 @@ export class PatientPage { cy.wait("@updatePatient").its("response.statusCode").should("eq", 200); } + clickCreateConsultationOnPatientPageWithNoConsultation() { + cy.get("#create-consultation").should("be.visible").click(); + } + verifyPatientUpdated() { cy.url().should("include", "/patient"); } @@ -237,4 +281,65 @@ export class PatientPage { patientformvisibility() { cy.get("[data-testid='current-address']").scrollIntoView(); } + + createPatientWithData(data: PatientData) { + this.createPatient(); + this.selectFacility(data.facility); + this.patientformvisibility(); + + this.typePatientPhoneNumber(data.phoneNumber); + if (data.isEmergencyNumber) { + this.checkPhoneNumberIsEmergencyNumber(); + } + this.typePatientAge(data.age.toString()); + this.typePatientName(data.name); + this.selectPatientGender(data.gender); + this.typePatientAddress(data.address); + + facilityPage.fillPincode(data.pincode); + facilityPage.selectStateOnPincode(data.state); + facilityPage.selectDistrictOnPincode(data.district); + facilityPage.selectLocalBody(data.localBody); + facilityPage.selectWard(data.ward); + + if (data.occupation) { + this.selectPatientOccupation(data.occupation); + } + if (data.socioeconomicStatus) { + this.selectSocioeconomicStatus(data.socioeconomicStatus); + } + if (data.domesticHealthcareSupport) { + this.selectDomesticHealthcareSupport(data.domesticHealthcareSupport); + } + + if (data.medicalHistory) { + if (data.medicalHistory.presentHealth) { + patientMedicalHistory.typePatientPresentHealth( + data.medicalHistory.presentHealth, + ); + } + if (data.medicalHistory.ongoingMedication) { + patientMedicalHistory.typePatientOngoingMedication( + data.medicalHistory.ongoingMedication, + ); + } + if (data.medicalHistory.conditions) { + data.medicalHistory.conditions.forEach(({ index, condition }) => { + patientMedicalHistory.typeMedicalHistory(index, condition); + }); + } + if (data.medicalHistory.allergies) { + patientMedicalHistory.typePatientAllergies( + data.medicalHistory.allergies, + ); + } + } + + if (data.bloodGroup) { + this.selectPatientBloodGroup(data.bloodGroup); + } + + this.clickCreatePatient(); + this.verifyPatientIsCreated(); + } } diff --git a/cypress/pageobject/Patient/PatientHome.ts b/cypress/pageobject/Patient/PatientHome.ts index 36cad15f0e5..a2147f70378 100644 --- a/cypress/pageobject/Patient/PatientHome.ts +++ b/cypress/pageobject/Patient/PatientHome.ts @@ -18,6 +18,10 @@ class PatientHome { cy.wait("@getPatients").its("response.statusCode").should("eq", 200); } + typePatientName(patientName: string) { + cy.typeAndSelectOption("input[name='name']", patientName); + } + typePatientCreatedBeforeDate(startDate: string) { cy.clickAndTypeDate("input[name='created_date_start']", startDate); } diff --git a/cypress/pageobject/Patient/PatientTreatmentPlan.ts b/cypress/pageobject/Patient/PatientTreatmentPlan.ts index 02b2f9b150d..7b4e08c8071 100644 --- a/cypress/pageobject/Patient/PatientTreatmentPlan.ts +++ b/cypress/pageobject/Patient/PatientTreatmentPlan.ts @@ -3,7 +3,7 @@ class PatientTreatmentPlan { cy.get("#consultation_notes").type(instruction); } - fillTreatingPhysican(doctor: string) { + fillTreatingPhysician(doctor: string) { cy.typeAndSelectOption("#treating_physician", doctor); } diff --git a/src/components/Facility/FacilityCard.tsx b/src/components/Facility/FacilityCard.tsx index 0d9c5678d4c..fbebe8a8d0a 100644 --- a/src/components/Facility/FacilityCard.tsx +++ b/src/components/Facility/FacilityCard.tsx @@ -106,7 +106,7 @@ export const FacilityCard = (props: { {t("live_patients_total_beds")} {" "} -
+
{t("occupancy")}: {facility.patient_count} /{" "} {facility.bed_count}{" "}
diff --git a/src/components/Patient/PatientHome.tsx b/src/components/Patient/PatientHome.tsx index a63f3202f98..8feea3c6d35 100644 --- a/src/components/Patient/PatientHome.tsx +++ b/src/components/Patient/PatientHome.tsx @@ -225,7 +225,10 @@ export const PatientHome = (props: { />
-

+

{patientData.name}

@@ -243,6 +246,7 @@ export const PatientHome = (props: { patientData?.last_consultation?.discharge_date) && (
From 05d89f4e301aaa1a96889053d36823268150844c Mon Sep 17 00:00:00 2001 From: Raj kumar <150310085+rajku-dev@users.noreply.github.com> Date: Wed, 11 Dec 2024 23:14:35 +0530 Subject: [PATCH 11/21] Changes on Assigning/Reassigning/Unassigning Volunteer to Patient (#9330) --- public/locale/en.json | 7 +++++-- src/components/Patient/PatientHome.tsx | 25 +++++++++++++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/public/locale/en.json b/public/locale/en.json index a37d6b4b115..4fb925ac941 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -354,6 +354,7 @@ "asset_type": "Asset Type", "assets": "Assets", "assign": "Assign", + "unassign":"Unassign", "assign_a_volunteer_to": "Assign a volunteer to {{name}}", "assign_bed": "Assign Bed", "assign_to_volunteer": "Assign to a Volunteer", @@ -1483,6 +1484,7 @@ "update_record_for_asset": "Update record for asset", "update_shift_request": "Update Shift Request", "update_status_details": "Update Status/Details", + "update_volunteer": "Reassign Volunteer", "updated": "Updated", "updated_on": "Updated On", "updating": "Updating", @@ -1553,9 +1555,10 @@ "vitals_monitor": "Vitals Monitor", "vitals_present": "Vitals Monitor present", "voice_autofill": "Voice Autofill", - "volunteer_assigned": "Volunteer assigned successfuly", + "volunteer_assigned": "Volunteer assigned successfully", "volunteer_contact": "Volunteer Contact", - "volunteer_unassigned": "Volunteer unassigned successfuly", + "volunteer_update" : "Volunteer updated successfully", + "volunteer_unassigned": "Volunteer unassigned successfully", "ward": "Ward", "warranty_amc_expiry": "Warranty / AMC Expiry", "weekly_working_hours_error": "Average weekly working hours must be a number between 0 and 168", diff --git a/src/components/Patient/PatientHome.tsx b/src/components/Patient/PatientHome.tsx index 8feea3c6d35..b69ae75751e 100644 --- a/src/components/Patient/PatientHome.tsx +++ b/src/components/Patient/PatientHome.tsx @@ -91,6 +91,8 @@ export const PatientHome = (props: { }); const handleAssignedVolunteer = async () => { + const previousVolunteerId = patientData?.assigned_to; + const { res, data } = await request(routes.patchPatient, { pathParams: { id: patientData.id as string, @@ -99,20 +101,29 @@ export const PatientHome = (props: { assigned_to: (assignedVolunteer as UserBareMinimum)?.id || null, }, }); + if (res?.ok && data) { setPatientData(data); - if (!assignedVolunteer) { + + if (!previousVolunteerId && assignedVolunteer) { Notification.Success({ msg: t("volunteer_assigned"), }); - } else { + } else if (previousVolunteerId && assignedVolunteer) { + Notification.Success({ + msg: t("volunteer_update"), + }); + } else if (!assignedVolunteer) { Notification.Success({ msg: t("volunteer_unassigned"), }); } + refetch(); } + setOpenAssignVolunteerDialog(false); + if (errors["assignedVolunteer"]) delete errors["assignedVolunteer"]; }; @@ -530,7 +541,9 @@ export const PatientHome = (props: { > {" "} - {t("assign_to_volunteer")} + {patientData.assigned_to + ? t("update_volunteer") + : t("assign_to_volunteer")}
@@ -713,7 +726,11 @@ export const PatientHome = (props: { />

} - action={t("assign")} + action={ + assignedVolunteer || !patientData.assigned_to + ? t("assign") + : t("unassign") + } onConfirm={handleAssignedVolunteer} /> From 1fb976b4aa2fae31a41271d2aa53f076f96a7502 Mon Sep 17 00:00:00 2001 From: Amjith Titus Date: Thu, 12 Dec 2024 12:45:14 +0530 Subject: [PATCH 12/21] Replace custom useQuery util with TanStack useQuery (#9360) --------- Co-authored-by: rithviknishad --- package-lock.json | 55 +++++ package.json | 4 +- src/App.tsx | 53 +++-- src/CAREUI/misc/PaginatedList.tsx | 12 +- src/Providers/AuthUserProvider.tsx | 4 +- src/Utils/featureFlags.tsx | 4 +- src/Utils/request/README.md | 189 ++++++++++++++---- src/Utils/request/request.ts | 62 ++---- src/Utils/request/types.ts | 1 - src/Utils/request/useMutation.ts | 10 +- src/Utils/request/useQuery.ts | 98 +++++---- src/components/Assets/AssetConfigure.tsx | 4 +- src/components/Assets/AssetFilter.tsx | 4 +- src/components/Assets/AssetImportModal.tsx | 11 +- src/components/Assets/AssetManage.tsx | 33 +-- .../Assets/AssetType/HL7Monitor.tsx | 4 +- src/components/Assets/AssetsList.tsx | 57 +++--- .../CameraFeed/CameraFeedWithBedPresets.tsx | 13 +- .../CentralLiveMonitoring/index.tsx | 6 +- src/components/CameraFeed/ConfigureCamera.tsx | 19 +- .../Common/DistrictAutocompleteFormField.tsx | 4 +- .../Common/LocalBodyAutocompleteFormField.tsx | 13 +- src/components/Common/LocationSelect.tsx | 4 +- .../Common/StateAutocompleteFormField.tsx | 4 +- src/components/Common/Uptime.tsx | 4 +- .../Common/UserAutocompleteFormField.tsx | 6 +- src/components/DeathReport/DeathReport.tsx | 4 +- .../AddICD11Diagnosis.tsx | 13 +- src/components/Facility/AddBedForm.tsx | 17 +- src/components/Facility/AddInventoryForm.tsx | 36 ++-- src/components/Facility/AddLocationForm.tsx | 37 ++-- src/components/Facility/AssetCreate.tsx | 15 +- src/components/Facility/BedManagement.tsx | 15 +- .../Facility/CentralNursingStation.tsx | 4 +- .../ConsultationFeedTab.tsx | 4 +- .../ConsultationUpdatesTab.tsx | 4 +- .../ConsultationVentilatorTab.tsx | 17 +- .../Facility/ConsultationDetails/index.tsx | 8 +- .../ConsultationDoctorNotes/index.tsx | 4 +- src/components/Facility/ConsultationForm.tsx | 39 ++-- .../Facility/Consultations/Beds.tsx | 4 +- src/components/Facility/DischargeModal.tsx | 4 +- .../Facility/DischargedPatientsList.tsx | 10 +- .../Facility/DoctorVideoSlideover.tsx | 4 +- .../Facility/FacilityBedCapacity.tsx | 4 +- src/components/Facility/FacilityConfigure.tsx | 4 +- src/components/Facility/FacilityCreate.tsx | 18 +- src/components/Facility/FacilityHome.tsx | 13 +- .../Facility/FacilityHomeTriage.tsx | 87 ++++---- src/components/Facility/FacilityList.tsx | 10 +- src/components/Facility/FacilityStaffList.tsx | 39 ++-- src/components/Facility/FacilityUsers.tsx | 23 ++- src/components/Facility/InventoryList.tsx | 34 ++-- src/components/Facility/InventoryLog.tsx | 15 +- .../InvestigationSuggestions.tsx | 13 +- .../InvestigationsPrintPreview.tsx | 23 ++- .../Facility/Investigations/Reports/index.tsx | 12 +- .../Investigations/ShowInvestigation.tsx | 85 ++++---- .../Facility/Investigations/index.tsx | 14 +- .../Investigations/investigationsTab.tsx | 12 +- .../Facility/LocationManagement.tsx | 4 +- src/components/Facility/MinQuantityList.tsx | 19 +- .../Facility/MinQuantityRequiredModal.tsx | 15 +- src/components/Facility/SetInventoryForm.tsx | 15 +- .../Facility/SpokeFacilityEditor.tsx | 4 +- src/components/Facility/StaffCapacity.tsx | 6 +- src/components/Facility/TreatmentSummary.tsx | 37 ++-- src/components/Facility/TriageForm.tsx | 8 +- src/components/Files/FileBlock.tsx | 4 +- src/components/Files/FileUpload.tsx | 8 +- src/components/HCX/InsurerAutocomplete.tsx | 11 +- .../HCX/PatientInsuranceDetailsEditor.tsx | 4 +- src/components/HCX/PolicyEligibilityCheck.tsx | 6 +- .../LogUpdate/CriticalCareEditor.tsx | 4 +- .../LogUpdate/CriticalCarePreview.tsx | 4 +- .../Sections/RespiratorySupport/index.tsx | 4 +- .../Medicine/CreatePrescriptionForm.tsx | 4 +- .../MedibaseAutocompleteFormField.tsx | 11 +- .../AdministrationTableRow.tsx | 4 +- .../MedicineAdministrationSheet/index.tsx | 23 ++- .../Medicine/MedicinePrescriptionSummary.tsx | 17 +- .../Medicine/PrescriptionBuilder.tsx | 21 +- .../Medicine/PrescriptionsTable.tsx | 4 +- .../Medicine/PrescrpitionTimeline.tsx | 4 +- src/components/Medicine/PrintPreview.tsx | 17 +- src/components/Notifications/NoticeBoard.tsx | 4 +- .../Notifications/ShowPushNotification.tsx | 4 +- .../Patient/DailyRoundListDetails.tsx | 19 +- src/components/Patient/DiagnosesFilter.tsx | 13 +- src/components/Patient/FileUploadPage.tsx | 4 +- src/components/Patient/InsuranceDetails.tsx | 4 +- src/components/Patient/ManagePatients.tsx | 43 ++-- .../Patient/PatientConsentRecords.tsx | 23 ++- .../Patient/PatientDetailsTab/Demography.tsx | 13 +- .../PatientDetailsTab/EncounterHistory.tsx | 31 +-- .../PatientDetailsTab/ShiftingHistory.tsx | 23 ++- src/components/Patient/PatientFilter.tsx | 8 +- src/components/Patient/PatientHome.tsx | 33 +-- src/components/Patient/PatientInfoCard.tsx | 4 +- src/components/Patient/PatientRegister.tsx | 22 +- src/components/Patient/SampleDetails.tsx | 4 +- src/components/Patient/SampleFilters.tsx | 21 +- src/components/Patient/SamplePreview.tsx | 4 +- src/components/Patient/SampleTest.tsx | 4 +- src/components/Patient/SampleViewAdmin.tsx | 17 +- src/components/Patient/ShiftCreate.tsx | 4 +- src/components/Resource/ResourceBadges.tsx | 4 +- src/components/Resource/ResourceCreate.tsx | 13 +- src/components/Resource/ResourceDetails.tsx | 4 +- .../Resource/ResourceDetailsUpdate.tsx | 40 ++-- src/components/Resource/ResourceFilter.tsx | 72 ++++--- src/components/Resource/ResourceList.tsx | 19 +- src/components/Shifting/ShiftDetails.tsx | 4 +- .../Shifting/ShiftDetailsUpdate.tsx | 19 +- src/components/Shifting/ShiftingBadges.tsx | 4 +- src/components/Shifting/ShiftingFilters.tsx | 77 +++---- src/components/Shifting/ShiftingList.tsx | 4 +- src/components/Symptoms/SymptomsBuilder.tsx | 4 +- src/components/Symptoms/SymptomsCard.tsx | 4 +- src/components/Users/LinkedFacilities.tsx | 39 ++-- src/components/Users/LinkedSkills.tsx | 4 +- src/components/Users/ManageUsers.tsx | 31 ++- src/components/Users/UserAddEditForm.tsx | 52 ++--- src/components/Users/UserAvatar.tsx | 4 +- src/components/Users/UserFilter.tsx | 4 +- src/components/Users/UserHome.tsx | 4 +- src/components/Users/UserProfile.tsx | 117 +++++------ 127 files changed, 1359 insertions(+), 1047 deletions(-) diff --git a/package-lock.json b/package-lock.json index 08ceb2deb4f..106518926f4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,6 +29,8 @@ "@radix-ui/react-toast": "^1.2.2", "@radix-ui/react-tooltip": "^1.1.4", "@sentry/browser": "^8.42.0", + "@tanstack/react-query": "^5.62.3", + "@tanstack/react-query-devtools": "^5.62.7", "@yudiel/react-qr-scanner": "^2.0.8", "bowser": "^2.11.0", "browser-image-compression": "^2.0.2", @@ -5324,6 +5326,59 @@ "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20" } }, + "node_modules/@tanstack/query-core": { + "version": "5.62.7", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.62.7.tgz", + "integrity": "sha512-fgpfmwatsrUal6V+8EC2cxZIQVl9xvL7qYa03gsdsCy985UTUlS4N+/3hCzwR0PclYDqisca2AqR1BVgJGpUDA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/query-devtools": { + "version": "5.61.4", + "resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.61.4.tgz", + "integrity": "sha512-21Tw+u8E3IJJj4A/Bct4H0uBaDTEu7zBrR79FeSyY+mS2gx5/m316oDtJiKkILc819VSTYt+sFzODoJNcpPqZQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.62.7", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.62.7.tgz", + "integrity": "sha512-+xCtP4UAFDTlRTYyEjLx0sRtWyr5GIk7TZjZwBu4YaNahi3Rt2oMyRqfpfVrtwsqY2sayP4iXVCwmC+ZqqFmuw==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.62.7" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18 || ^19" + } + }, + "node_modules/@tanstack/react-query-devtools": { + "version": "5.62.7", + "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.62.7.tgz", + "integrity": "sha512-wxXsdTZJRs//hMtJMU5aNlUaTclRFPqLvDNeWbRj8YpGD3aoo4zyu53W55W2DY16+ycg3fti21uCW4N9oyj91w==", + "license": "MIT", + "dependencies": { + "@tanstack/query-devtools": "5.61.4" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "@tanstack/react-query": "^5.62.7", + "react": "^18 || ^19" + } + }, "node_modules/@tanstack/react-virtual": { "version": "3.10.8", "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.10.8.tgz", diff --git a/package.json b/package.json index 8fd129463e4..7bc7e5c117b 100644 --- a/package.json +++ b/package.json @@ -60,14 +60,16 @@ "@pnotify/mobile": "^5.2.0", "@radix-ui/react-dialog": "^1.1.2", "@radix-ui/react-dropdown-menu": "^2.1.2", + "@radix-ui/react-icons": "^1.3.2", "@radix-ui/react-label": "^2.1.0", "@radix-ui/react-popover": "^1.1.2", "@radix-ui/react-scroll-area": "^1.2.0", - "@radix-ui/react-icons": "^1.3.2", "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-toast": "^1.2.2", "@radix-ui/react-tooltip": "^1.1.4", "@sentry/browser": "^8.42.0", + "@tanstack/react-query": "^5.62.3", + "@tanstack/react-query-devtools": "^5.62.7", "@yudiel/react-qr-scanner": "^2.0.8", "bowser": "^2.11.0", "browser-image-compression": "^2.0.2", diff --git a/src/App.tsx b/src/App.tsx index d3fec38dbed..c91849de559 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,3 +1,5 @@ +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; import { Suspense } from "react"; import { Toaster } from "@/components/ui/toaster"; @@ -13,26 +15,41 @@ import { FeatureFlagsProvider } from "@/Utils/featureFlags"; import { PubSubProvider } from "./Utils/pubsubContext"; +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: 3, + refetchOnWindowFocus: false, + staleTime: 5 * 60 * 1000, // 5 minutes + }, + }, +}); + const App = () => { return ( - }> - - - - }> - - - - - - {/* Integrations */} - - - - - - - + + }> + + + + }> + + + + + + {/* Integrations */} + + + + + + + + + {/* Devtools are not included in production builds by default */} + + ); }; diff --git a/src/CAREUI/misc/PaginatedList.tsx b/src/CAREUI/misc/PaginatedList.tsx index 1c5f9db99a2..6379b8b7ad8 100644 --- a/src/CAREUI/misc/PaginatedList.tsx +++ b/src/CAREUI/misc/PaginatedList.tsx @@ -6,13 +6,15 @@ import ButtonV2, { CommonButtonProps } from "@/components/Common/ButtonV2"; import Pagination from "@/components/Common/Pagination"; import { PaginatedResponse, QueryRoute } from "@/Utils/request/types"; -import useQuery, { QueryOptions } from "@/Utils/request/useQuery"; +import useTanStackQueryInstead, { + QueryOptions, +} from "@/Utils/request/useQuery"; import { classNames } from "@/Utils/utils"; const DEFAULT_PER_PAGE_LIMIT = 14; interface PaginatedListContext - extends ReturnType>> { + extends ReturnType>> { items: TItem[]; perPage: number; currentPage: number; @@ -37,11 +39,11 @@ interface Props extends QueryOptions> { initialPage?: number; onPageChange?: (page: number) => void; queryCB?: ( - query: ReturnType>>, + query: ReturnType>>, ) => void; children: ( ctx: PaginatedListContext, - query: ReturnType>>, + query: ReturnType>>, ) => JSX.Element | JSX.Element[]; } @@ -59,7 +61,7 @@ export default function PaginatedList({ queryOptions.onPageChange?.(page); }; - const query = useQuery(route, { + const query = useTanStackQueryInstead(route, { ...queryOptions, query: { ...queryOptions.query, diff --git a/src/Providers/AuthUserProvider.tsx b/src/Providers/AuthUserProvider.tsx index 1e4545f64a2..7aac5803de2 100644 --- a/src/Providers/AuthUserProvider.tsx +++ b/src/Providers/AuthUserProvider.tsx @@ -10,7 +10,7 @@ import { LocalStorageKeys } from "@/common/constants"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; interface Props { children: React.ReactNode; @@ -23,7 +23,7 @@ export default function AuthUserProvider({ children, unauthorized }: Props) { data: user, loading, refetch, - } = useQuery(routes.currentUser, { silent: true }); + } = useTanStackQueryInstead(routes.currentUser, { silent: true }); useEffect(() => { if (!user) { diff --git a/src/Utils/featureFlags.tsx b/src/Utils/featureFlags.tsx index a475bee57d6..98d1cbebbf7 100644 --- a/src/Utils/featureFlags.tsx +++ b/src/Utils/featureFlags.tsx @@ -5,7 +5,7 @@ import { FacilityModel } from "@/components/Facility/models"; import useAuthUser from "@/hooks/useAuthUser"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; export type FeatureFlag = "SCRIBE_ENABLED"; // "HCX_ENABLED" | "ABDM_ENABLED" | @@ -60,7 +60,7 @@ export const useFeatureFlags = (facility?: FacilityModel | string) => { ); } - const facilityQuery = useQuery(routes.getPermittedFacility, { + const facilityQuery = useTanStackQueryInstead(routes.getPermittedFacility, { pathParams: { id: typeof facility === "string" ? facility : "", }, diff --git a/src/Utils/request/README.md b/src/Utils/request/README.md index ca3e2232043..0780d3149f6 100644 --- a/src/Utils/request/README.md +++ b/src/Utils/request/README.md @@ -1,25 +1,162 @@ -# CARE's data fetching utilities: `useQuery` and `request` +# CARE's data fetching utilities -There are two main ways to fetch data in CARE: `useQuery` and `request`. Both of these utilities are built on top of [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch). +CARE now uses TanStack Query (formerly React Query) as its data fetching solution. For backward compatibility, we maintain a wrapper `useTanStackQueryInstead` that provides the same API as our previous `useQuery` hook. -## `useQuery` +## Using TanStack Query (Recommended for new code) -`useQuery` is a React hook that allows you to fetch data and automatically update the UI when the data changes. It is -a wrapper around `request` that is designed to be used in React components. Only "GET" requests are supported with `useQuery`. For other request methods (mutations), use `request`. +For new API integrations, we recommend using TanStack Query directly: -### Usage +```tsx +import { useQuery } from "@tanstack/react-query"; +import request from "@/Utils/request/request"; +import FooRoutes from "@foo/routes"; + +export default function FooDetails({ id }) { + const { data, isLoading, error } = useQuery({ + queryKey: [FooRoutes.getFoo.path, id], + queryFn: async () => { + const response = await request(FooRoutes.getFoo, { + pathParams: { id } + }); + return response.data; + } + }); + + if (isLoading) return ; + if (error) return ; + + return ( +
+ {data.id} + {data.name} +
+ ); +} +``` + +## Migration Guide & Reference + +### Understanding the Transition + +Our codebase contains two patterns for data fetching: +1. Legacy pattern using `useTanStackQueryInstead` (wrapper around TanStack Query) +2. Modern pattern using TanStack Query directly + +### Pattern Comparison + +Here's the same API call implemented both ways: + +```tsx +// Legacy Pattern (existing code) +function LegacyComponent({ id }) { + const { data, loading, error, refetch } = useTanStackQueryInstead(UserRoutes.getUser, { + pathParams: { id }, + prefetch: true, + refetchOnWindowFocus: false + }); +} + +// Modern Pattern (new code) +function ModernComponent({ id }) { + const { data, isLoading, error, refetch } = useQuery({ + queryKey: [UserRoutes.getUser.path, id], + queryFn: async () => { + const response = await request(UserRoutes.getUser, { + pathParams: { id } + }); + return response.data; + }, + enabled: true, + refetchOnWindowFocus: false + }); +} +``` + +### Migration Mapping + +When migrating from `useTanStackQueryInstead` to direct TanStack Query usage: + +```typescript +// Legacy options -> TanStack Query options +{ + prefetch: true -> enabled: true + loading -> isLoading + refetchOnWindowFocus: false -> refetchOnWindowFocus: false + + // Response structure + data -> data (direct access, no .data property) + res.status -> Use error handling or onError callback + error -> error +} +``` + +### Common Patterns + +1. **Conditional Fetching**: +```tsx +// Legacy +useTanStackQueryInstead(route, { prefetch: shouldFetch }) + +// Modern +useQuery({ + queryKey: [route.path], + queryFn: async () => (await request(route)).data, + enabled: shouldFetch +}) +``` + +2. **With Parameters**: +```tsx +// Legacy +useTanStackQueryInstead(route, { + pathParams: { id }, + query: { filter } +}) + +// Modern +useQuery({ + queryKey: [route.path, id, filter], + queryFn: async () => { + const response = await request(route, { + pathParams: { id }, + query: { filter } + }); + return response.data; + } +}) +``` + +3. **Error Handling**: +```tsx +// Legacy +const { error, res } = useTanStackQueryInstead(route); +if (res?.status === 403) handleForbidden(); + +// Modern +useQuery({ + queryKey: [route.path], + queryFn: async () => { + const response = await request(route); + if (response.res.status === 403) handleForbidden(); + return response.data; + }, + onError: (error) => handleError(error) +}) +``` + +## Legacy Support: `useTanStackQueryInstead` + +For existing code or maintaining consistency with older patterns, use our wrapper around TanStack Query: ```jsx -import { useQuery } from "@care/request"; +import { useTanStackQueryInstead } from "@care/request"; import FooRoutes from "@foo/routes"; export default function FooDetails({ children, id }) { - const { res, data, loading, error } = useQuery(FooRoutes.getFoo, { + const { res, data, loading, error } = useTanStackQueryInstead(FooRoutes.getFoo, { pathParams: { id }, }); - /* 🪄 Here typeof data is automatically inferred from the specified route. */ - if (loading) return ; if (res.status === 403) { @@ -43,7 +180,7 @@ export default function FooDetails({ children, id }) { ### API ```ts -useQuery(route: Route, options?: QueryOptions): ReturnType; +useTanStackQueryInstead(route: Route, options?: QueryOptions): ReturnType; ``` #### `route` @@ -54,7 +191,6 @@ A route object that specifies the endpoint to fetch data from. const FooRoutes = { getFoo: { path: "/api/v1/foo/{id}/", // 👈 The path to the endpoint. Slug parameters can be specified using curly braces. - method: "GET", // 👈 The HTTP method to use. Optional; defaults to "GET". TRes: Type(), // 👈 The type of the response body (for type inference). TBody: Type(), // 👈 The type of the request body (for type inference). @@ -73,54 +209,37 @@ const options = { refetchOnWindowFocus: true, // 👈 Whether to refetch the data when the window regains focus. // The following options are passed directly to the underlying `request` function. - pathParams: { id: "123" }, // 👈 The slug parameters to use in the path. - // If you accidentally forget to specify a slug parameter an error will be - // thrown before the request is made. - query: { limit: 10 }, // 👈 The query parameters to be added to the request URL. - body: { name: "foo" }, // 👈 The body to be sent with the request. Should be compatible with the TBody type of the route. - headers: { "X-Foo": "bar" }, // 👈 Additional headers to be sent with the request. (Coming soon...) - + body: { name: "foo" }, // 👈 The body to be sent with the request. + headers: { "X-Foo": "bar" }, // 👈 Additional headers to be sent with the request. silent: true, // 👈 Whether to suppress notifications for this request. - // This is useful for requests that are made in the background. - - reattempts: 3, // 👈 The number of times to retry the request if it fails. - // Reattempts are only made if the request fails due to a network error. Responses with - // status codes in the 400s and 500s are not retried. onResponse: (res) => { - // 👈 An optional callback that is called after the response is received. if (res.status === 403) { navigate("/forbidden"); } }, - // This is useful for handling responses with status codes in the 400s and 500s for a specific request. }; ``` -#### `ReturnType` +#### Return Type -The `useQuery` hook returns an object with the following properties: +The hook returns an object with the following properties: ```ts { res: Type | undefined; // 👈 The response object. `undefined` if the request has not been made yet. - data: TRes | null; // 👈 The response body. `null` if the request has not been made yet. - error: any; // 👈 The error that occurred while making the request if any. - loading: boolean; // 👈 Whether the request is currently in progress. - refetch: () => void; // 👈 A function that can be called to refetch the data. - // Ideal for revalidating stale data after a mutation. } ``` ## `request` -`request` is a function that allows you to fetch data. It is a wrapper around `fetch` that adds some useful features. It can be used in both React components and non-React code. For fetching data in React components, prefer using `useQuery`. For mutations, use `request`. +`request` is a function that allows you to fetch data. It is a wrapper around `fetch` that adds some useful features. It can be used in both React components and non-React code. For fetching data in React components, prefer using TanStack Query or `useTanStackQueryInstead`. For mutations, use `request`. ### `request` usage @@ -131,7 +250,7 @@ import FooRoutes from "@foo/routes"; export default async function updateFoo(id: string, object: Foo) { const { res, data } = await request(FooRoutes.updateFoo, { pathParams: { id }, - body: object, // 👈 The body is automatically serialized to JSON. Should be compatible with the TBody type of the route. + body: object, // 👈 The body is automatically serialized to JSON. }); if (res.status === 403) { diff --git a/src/Utils/request/request.ts b/src/Utils/request/request.ts index 847b7c9ba60..73bc9763f50 100644 --- a/src/Utils/request/request.ts +++ b/src/Utils/request/request.ts @@ -4,18 +4,9 @@ import handleResponse from "@/Utils/request/handleResponse"; import { RequestOptions, RequestResult, Route } from "@/Utils/request/types"; import { makeHeaders, makeUrl } from "@/Utils/request/utils"; -type ControllerXORControllerRef = - | { - controller?: AbortController; - controllerRef?: undefined; - } - | { - controller?: undefined; - controllerRef: React.MutableRefObject; - }; - -type Options = RequestOptions & - ControllerXORControllerRef; +type Options = RequestOptions & { + signal?: AbortSignal; +}; export default async function request( { path, method, noAuth }: Route, @@ -23,19 +14,11 @@ export default async function request( query, body, pathParams, - controller, - controllerRef, onResponse, silent, - reattempts = 3, + signal, }: Options = {}, ): Promise> { - if (controllerRef) { - controllerRef.current?.abort(); - controllerRef.current = new AbortController(); - } - - const signal = controller?.signal ?? controllerRef?.current?.signal; const url = `${careConfig.apiUrl}${makeUrl(path, query, pathParams)}`; const options: RequestInit = { method, signal }; @@ -50,36 +33,31 @@ export default async function request( error: undefined, }; - for (let i = 0; i < reattempts + 1; i++) { - options.headers = makeHeaders(noAuth ?? false); + options.headers = makeHeaders(noAuth ?? false); - try { - const res = await fetch(url, options); + try { + const res = await fetch(url, options); - const data = await getResponseBody(res); + const data = await getResponseBody(res); - result = { - res, - data: res.ok ? data : undefined, - error: res.ok ? undefined : (data as Record), - }; + result = { + res, + data: res.ok ? data : undefined, + error: res.ok ? undefined : (data as Record), + }; - onResponse?.(result); - handleResponse(result, silent); + onResponse?.(result); + handleResponse(result, silent); + return result; + } catch (error: any) { + result = { error, res: undefined, data: undefined }; + if (error.name === "AbortError") { return result; - } catch (error: any) { - result = { error, res: undefined, data: undefined }; - if (error.name === "AbortError") { - return result; - } } } - console.error( - `Request failed after ${reattempts + 1} attempts`, - result.error, - ); + console.error(`Request failed `, result.error); return result; } diff --git a/src/Utils/request/types.ts b/src/Utils/request/types.ts index aed066ac81c..668f937dbf0 100644 --- a/src/Utils/request/types.ts +++ b/src/Utils/request/types.ts @@ -33,7 +33,6 @@ export interface RequestOptions { pathParams?: Record; onResponse?: (res: RequestResult) => void; silent?: boolean; - reattempts?: number; } export interface PaginatedResponse { diff --git a/src/Utils/request/useMutation.ts b/src/Utils/request/useMutation.ts index 7c368f5e45d..cff4919a6bd 100644 --- a/src/Utils/request/useMutation.ts +++ b/src/Utils/request/useMutation.ts @@ -8,7 +8,10 @@ import { } from "@/Utils/request/types"; import { mergeRequestOptions } from "@/Utils/request/utils"; -export default function useMutation( +/** + * @deprecated use `useMutation` from `@tanstack/react-query` instead. + */ +export default function useDeprecatedMutation( route: MutationRoute, options: RequestOptions, ) { @@ -30,7 +33,10 @@ export default function useMutation( : (overrides ?? options); setIsProcessing(true); - const response = await request(route, { ...resolvedOptions, controller }); + const response = await request(route, { + ...resolvedOptions, + signal: controller.signal, + }); if (response.error?.name !== "AbortError") { setResponse(response); setIsProcessing(false); diff --git a/src/Utils/request/useQuery.ts b/src/Utils/request/useQuery.ts index 5f4c10a289e..a0d337a1aa8 100644 --- a/src/Utils/request/useQuery.ts +++ b/src/Utils/request/useQuery.ts @@ -1,66 +1,58 @@ -import { useCallback, useEffect, useRef, useState } from "react"; +import { useQuery } from "@tanstack/react-query"; +import { useMemo, useRef } from "react"; import request from "@/Utils/request/request"; -import { - QueryRoute, - RequestOptions, - RequestResult, -} from "@/Utils/request/types"; -import { mergeRequestOptions } from "@/Utils/request/utils"; +import { QueryRoute, RequestOptions } from "@/Utils/request/types"; + +import { mergeRequestOptions } from "./utils"; export interface QueryOptions extends RequestOptions { prefetch?: boolean; - refetchOnWindowFocus?: boolean; key?: string; } -export default function useQuery( +/** + * @deprecated use `useQuery` from `@tanstack/react-query` instead. + */ +export default function useTanStackQueryInstead( route: QueryRoute, options?: QueryOptions, ) { - const [response, setResponse] = useState>(); - const [loading, setLoading] = useState(false); - - const controllerRef = useRef(); - - const runQuery = useCallback( - async (overrides?: QueryOptions) => { - controllerRef.current?.abort(); - - const controller = new AbortController(); - controllerRef.current = controller; - - const resolvedOptions = - options && overrides - ? mergeRequestOptions(options, overrides) - : (overrides ?? options); - - setLoading(true); - const response = await request(route, { ...resolvedOptions, controller }); - if (response.error?.name !== "AbortError") { - setResponse(response); - setLoading(false); - } - return response; + const overridesRef = useRef>(); + + // Ensure unique key for each usage of the hook unless explicitly provided + // (hack to opt-out of tanstack query's caching between usages) + const key = useMemo(() => options?.key ?? Math.random(), [options?.key]); + + const { + data: response, + refetch, + isFetching: isLoading, + } = useQuery({ + queryKey: [route.path, options?.pathParams, options?.query, key], + queryFn: async ({ signal }) => { + const resolvedOptions = overridesRef.current + ? mergeRequestOptions(options || {}, overridesRef.current) + : options; + + return await request(route, { ...resolvedOptions, signal }); }, - [route, JSON.stringify(options)], - ); - - useEffect(() => { - if (options?.prefetch ?? true) { - runQuery(); - } - }, [runQuery, options?.prefetch]); - - useEffect(() => { - if (options?.refetchOnWindowFocus) { - const onFocus = () => runQuery(); - - window.addEventListener("focus", onFocus); - - return () => window.removeEventListener("focus", onFocus); - } - }, [runQuery, options?.refetchOnWindowFocus]); - - return { ...response, loading, refetch: runQuery }; + enabled: options?.prefetch ?? true, + refetchOnWindowFocus: false, + }); + + return { + data: response?.data, + loading: isLoading, + error: response?.error, + res: response?.res, + /** + * Refetch function that applies new options and fetches fresh data. + */ + refetch: async (overrides?: QueryOptions) => { + overridesRef.current = overrides; + await refetch(); + return response!; + }, + }; } diff --git a/src/components/Assets/AssetConfigure.tsx b/src/components/Assets/AssetConfigure.tsx index d0d3e4f9420..c3c9f38071d 100644 --- a/src/components/Assets/AssetConfigure.tsx +++ b/src/components/Assets/AssetConfigure.tsx @@ -4,7 +4,7 @@ import Loading from "@/components/Common/Loading"; import Page from "@/components/Common/Page"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; interface AssetConfigureProps { assetId: string; @@ -12,7 +12,7 @@ interface AssetConfigureProps { } const AssetConfigure = ({ assetId, facilityId }: AssetConfigureProps) => { - const { data: asset, refetch } = useQuery(routes.getAsset, { + const { data: asset, refetch } = useTanStackQueryInstead(routes.getAsset, { pathParams: { external_id: assetId }, }); diff --git a/src/components/Assets/AssetFilter.tsx b/src/components/Assets/AssetFilter.tsx index fda9d0cfdf2..70e2729c769 100644 --- a/src/components/Assets/AssetFilter.tsx +++ b/src/components/Assets/AssetFilter.tsx @@ -15,7 +15,7 @@ import { SelectFormField } from "@/components/Form/FormFields/SelectFormField"; import { FieldChangeEvent } from "@/components/Form/FormFields/Utils"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { dateQueryString } from "@/Utils/utils"; const getDate = (value: any) => @@ -36,7 +36,7 @@ function AssetFilter(props: any) { }); const [qParams, _] = useQueryParams(); - useQuery(routes.getPermittedFacility, { + useTanStackQueryInstead(routes.getPermittedFacility, { pathParams: { id: facilityId }, onResponse: ({ res, data }) => { if (res?.status === 200 && data) { diff --git a/src/components/Assets/AssetImportModal.tsx b/src/components/Assets/AssetImportModal.tsx index beb0dd2c2c1..9090834bf44 100644 --- a/src/components/Assets/AssetImportModal.tsx +++ b/src/components/Assets/AssetImportModal.tsx @@ -13,7 +13,7 @@ import { AssetImportSchema } from "@/common/constants"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { sleep } from "@/Utils/utils"; const ExcelFileDragAndDrop = lazy( @@ -38,9 +38,12 @@ const AssetImportModal = ({ open, onClose, facility, onUpdate }: Props) => { const closeModal = () => { onClose && onClose(); }; - const { data, loading } = useQuery(routes.listFacilityAssetLocation, { - pathParams: { facility_external_id: `${facility.id}` }, - }); + const { data, loading } = useTanStackQueryInstead( + routes.listFacilityAssetLocation, + { + pathParams: { facility_external_id: `${facility.id}` }, + }, + ); const locations = data?.results || []; diff --git a/src/components/Assets/AssetManage.tsx b/src/components/Assets/AssetManage.tsx index b4377d2e1aa..64938515a63 100644 --- a/src/components/Assets/AssetManage.tsx +++ b/src/components/Assets/AssetManage.tsx @@ -34,7 +34,7 @@ import { NonReadOnlyUsers } from "@/Utils/AuthorizeFor"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { formatDate, formatDateTime, formatName } from "@/Utils/utils"; interface AssetManageProps { @@ -73,7 +73,7 @@ const AssetManage = (props: AssetManageProps) => { data: asset, loading, refetch, - } = useQuery(routes.getAsset, { + } = useTanStackQueryInstead(routes.getAsset, { pathParams: { external_id: assetId, }, @@ -88,21 +88,24 @@ const AssetManage = (props: AssetManageProps) => { }, }); - const { data: transactions } = useQuery(routes.listAssetTransaction, { - prefetch: !!asset, - query: { - ...transactionFilter, - limit, - offset, - }, - onResponse: ({ res, data }) => { - if (res?.status === 200 && data) { - setTotalCount(data.count); - } + const { data: transactions } = useTanStackQueryInstead( + routes.listAssetTransaction, + { + prefetch: !!asset, + query: { + ...transactionFilter, + limit, + offset, + }, + onResponse: ({ res, data }) => { + if (res?.status === 200 && data) { + setTotalCount(data.count); + } + }, }, - }); + ); - const { data: services, refetch: serviceRefetch } = useQuery( + const { data: services, refetch: serviceRefetch } = useTanStackQueryInstead( routes.listAssetService, { pathParams: { diff --git a/src/components/Assets/AssetType/HL7Monitor.tsx b/src/components/Assets/AssetType/HL7Monitor.tsx index 76d761383bd..269deacbf58 100644 --- a/src/components/Assets/AssetType/HL7Monitor.tsx +++ b/src/components/Assets/AssetType/HL7Monitor.tsx @@ -24,7 +24,7 @@ import { checkIfValidIP } from "@/common/validation"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; interface HL7MonitorProps { assetId: string; @@ -191,7 +191,7 @@ const updateLink = async ( function MonitorConfigure({ asset }: { asset: AssetData }) { const [bed, setBed] = useState({}); const [shouldUpdateLink, setShouldUpdateLink] = useState(false); - const { data: assetBed } = useQuery(routes.listAssetBeds, { + const { data: assetBed } = useTanStackQueryInstead(routes.listAssetBeds, { query: { asset: asset.id }, onResponse: ({ res, data }) => { if (res?.status === 200 && data && data.results.length > 0) { diff --git a/src/components/Assets/AssetsList.tsx b/src/components/Assets/AssetsList.tsx index 685d7dfa460..c0e47610766 100644 --- a/src/components/Assets/AssetsList.tsx +++ b/src/components/Assets/AssetsList.tsx @@ -27,7 +27,7 @@ import * as Notification from "@/Utils/Notifications"; import { parseQueryParams } from "@/Utils/primitives"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; const AssetsList = () => { const { t } = useTranslation(); @@ -68,26 +68,32 @@ const AssetsList = () => { qParams.warranty_amc_end_of_validity_after || "", }; - const { refetch: assetsFetch, loading } = useQuery(routes.listAssets, { - query: params, - onResponse: ({ res, data }) => { - if (res?.status === 200 && data) { - setAssets(data.results); - setTotalCount(data.count); - } + const { refetch: assetsFetch, loading } = useTanStackQueryInstead( + routes.listAssets, + { + query: params, + onResponse: ({ res, data }) => { + if (res?.status === 200 && data) { + setAssets(data.results); + setTotalCount(data.count); + } + }, }, - }); + ); - const { data: facilityObject } = useQuery(routes.getAnyFacility, { - pathParams: { id: qParams.facility }, - onResponse: ({ res, data }) => { - if (res?.status === 200 && data) { - setFacility(data); - setSelectedFacility(data); - } + const { data: facilityObject } = useTanStackQueryInstead( + routes.getAnyFacility, + { + pathParams: { id: qParams.facility }, + onResponse: ({ res, data }) => { + if (res?.status === 200 && data) { + setFacility(data); + setSelectedFacility(data); + } + }, + prefetch: !!qParams.facility, }, - prefetch: !!qParams.facility, - }); + ); useEffect(() => { setStatus(qParams.status); @@ -97,13 +103,16 @@ const AssetsList = () => { setAssetClass(qParams.asset_class); }, [qParams.asset_class]); - const { data: locationObject } = useQuery(routes.getFacilityAssetLocation, { - pathParams: { - facility_external_id: String(qParams.facility), - external_id: String(qParams.location), + const { data: locationObject } = useTanStackQueryInstead( + routes.getFacilityAssetLocation, + { + pathParams: { + facility_external_id: String(qParams.facility), + external_id: String(qParams.location), + }, + prefetch: !!(qParams.facility && qParams.location), }, - prefetch: !!(qParams.facility && qParams.location), - }); + ); function isValidURL(url: string) { try { diff --git a/src/components/CameraFeed/CameraFeedWithBedPresets.tsx b/src/components/CameraFeed/CameraFeedWithBedPresets.tsx index be43fe3f810..53d04bed6a3 100644 --- a/src/components/CameraFeed/CameraFeedWithBedPresets.tsx +++ b/src/components/CameraFeed/CameraFeedWithBedPresets.tsx @@ -6,7 +6,7 @@ import { CameraPresetDropdown } from "@/components/CameraFeed/CameraPresetSelect import { CameraPreset, FeedRoutes } from "@/components/CameraFeed/routes"; import useOperateCamera from "@/components/CameraFeed/useOperateCamera"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { classNames } from "@/Utils/utils"; interface Props { @@ -16,10 +16,13 @@ interface Props { export default function LocationFeedTile(props: Props) { const [preset, setPreset] = useState(); const { operate, key } = useOperateCamera(props.asset.id); - const { data, loading } = useQuery(FeedRoutes.listAssetPresets, { - pathParams: { asset_id: props.asset.id }, - query: { limit: 100 }, - }); + const { data, loading } = useTanStackQueryInstead( + FeedRoutes.listAssetPresets, + { + pathParams: { asset_id: props.asset.id }, + query: { limit: 100 }, + }, + ); return ( bed.id === selectedBedId, ); - const cameraPresetsQuery = useQuery(FeedRoutes.listAssetBedPresets, { - pathParams: { assetbed_id: selectedAssetBed?.id ?? "" }, - query: { position: true, limit: 50 }, - prefetch: !!selectedAssetBed?.id, - }); + const cameraPresetsQuery = useTanStackQueryInstead( + FeedRoutes.listAssetBedPresets, + { + pathParams: { assetbed_id: selectedAssetBed?.id ?? "" }, + query: { position: true, limit: 50 }, + prefetch: !!selectedAssetBed?.id, + }, + ); useEffect(() => setMeta(props.asset.meta), [props.asset]); diff --git a/src/components/Common/DistrictAutocompleteFormField.tsx b/src/components/Common/DistrictAutocompleteFormField.tsx index 91f1c9389f8..268af902c90 100644 --- a/src/components/Common/DistrictAutocompleteFormField.tsx +++ b/src/components/Common/DistrictAutocompleteFormField.tsx @@ -3,7 +3,7 @@ import AutocompleteFormField from "@/components/Form/FormFields/Autocomplete"; import { FormFieldBaseProps } from "@/components/Form/FormFields/Utils"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; type Props = FormFieldBaseProps & { placeholder?: string; @@ -11,7 +11,7 @@ type Props = FormFieldBaseProps & { }; export default function DistrictAutocompleteFormField(props: Props) { - const { data, loading } = useQuery(routes.getDistrictByState, { + const { data, loading } = useTanStackQueryInstead(routes.getDistrictByState, { pathParams: { id: props.state! }, prefetch: !!props.state, }); diff --git a/src/components/Common/LocalBodyAutocompleteFormField.tsx b/src/components/Common/LocalBodyAutocompleteFormField.tsx index 1ed5a997007..b64d5ab04f3 100644 --- a/src/components/Common/LocalBodyAutocompleteFormField.tsx +++ b/src/components/Common/LocalBodyAutocompleteFormField.tsx @@ -3,7 +3,7 @@ import AutocompleteFormField from "@/components/Form/FormFields/Autocomplete"; import { FormFieldBaseProps } from "@/components/Form/FormFields/Utils"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; type Props = FormFieldBaseProps & { placeholder?: string; @@ -11,10 +11,13 @@ type Props = FormFieldBaseProps & { }; export default function LocalBodyAutocompleteFormField(props: Props) { - const { data, loading } = useQuery(routes.getLocalbodyByDistrict, { - pathParams: { id: props.district! }, - prefetch: !!props.district, - }); + const { data, loading } = useTanStackQueryInstead( + routes.getLocalbodyByDistrict, + { + pathParams: { id: props.district! }, + prefetch: !!props.district, + }, + ); return ( { - const { data, loading, refetch } = useQuery( + const { data, loading, refetch } = useTanStackQueryInstead( routes.listFacilityAssetLocation, { query: { diff --git a/src/components/Common/StateAutocompleteFormField.tsx b/src/components/Common/StateAutocompleteFormField.tsx index e184ae0ffd7..0bb0945c6f2 100644 --- a/src/components/Common/StateAutocompleteFormField.tsx +++ b/src/components/Common/StateAutocompleteFormField.tsx @@ -3,14 +3,14 @@ import AutocompleteFormField from "@/components/Form/FormFields/Autocomplete"; import { FormFieldBaseProps } from "@/components/Form/FormFields/Utils"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; type Props = FormFieldBaseProps & { placeholder?: string; }; export default function StateAutocompleteFormField(props: Props) { - const { data, loading } = useQuery(routes.statesList); + const { data, loading } = useTanStackQueryInstead(routes.statesList); return ( ([]); - const { data, loading } = useQuery(props.route, { + const { data, loading } = useTanStackQueryInstead(props.route, { pathParams: props.params, onResponse: ({ data }) => setUptimeRecord(data?.results.reverse() ?? []), }); diff --git a/src/components/Common/UserAutocompleteFormField.tsx b/src/components/Common/UserAutocompleteFormField.tsx index 47381414221..2cc34522fad 100644 --- a/src/components/Common/UserAutocompleteFormField.tsx +++ b/src/components/Common/UserAutocompleteFormField.tsx @@ -11,7 +11,7 @@ import { UserBareMinimum } from "@/components/Users/models"; import { UserRole } from "@/common/constants"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { classNames, formatName, @@ -42,7 +42,7 @@ export default function UserAutocomplete(props: UserSearchProps) { const [query, setQuery] = useState(""); const [disabled, setDisabled] = useState(false); - const { data, loading } = useQuery(routes.userList, { + const { data, loading } = useTanStackQueryInstead(routes.userList, { query: { home_facility: props.homeFacility, user_type: props.userType, @@ -112,7 +112,7 @@ export const LinkedFacilityUsers = (props: LinkedFacilitySearchProps) => { const [query, setQuery] = useState(""); - const { data, loading } = useQuery(routes.getFacilityUsers, { + const { data, loading } = useTanStackQueryInstead(routes.getFacilityUsers, { pathParams: { facility_id: props.facilityId }, query: { user_type: props.userType, diff --git a/src/components/DeathReport/DeathReport.tsx b/src/components/DeathReport/DeathReport.tsx index 7f2b3cddfcc..41f2f728b7a 100644 --- a/src/components/DeathReport/DeathReport.tsx +++ b/src/components/DeathReport/DeathReport.tsx @@ -15,7 +15,7 @@ import TextFormField from "@/components/Form/FormFields/TextFormField"; import { GENDER_TYPES } from "@/common/constants"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { formatDateTime, formatPatientAge, @@ -103,7 +103,7 @@ export default function PrintDeathReport(props: { id: string }) { } }; - const { loading: _isLoading } = useQuery(routes.getPatient, { + const { loading: _isLoading } = useTanStackQueryInstead(routes.getPatient, { pathParams: { id }, onResponse(res) { if (res.res?.ok && res) { diff --git a/src/components/Diagnosis/ConsultationDiagnosisBuilder/AddICD11Diagnosis.tsx b/src/components/Diagnosis/ConsultationDiagnosisBuilder/AddICD11Diagnosis.tsx index e864ed139c5..d2e21263b26 100644 --- a/src/components/Diagnosis/ConsultationDiagnosisBuilder/AddICD11Diagnosis.tsx +++ b/src/components/Diagnosis/ConsultationDiagnosisBuilder/AddICD11Diagnosis.tsx @@ -11,7 +11,7 @@ import AutocompleteFormField from "@/components/Form/FormFields/Autocomplete"; import { Error } from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { classNames, mergeQueryOptions } from "@/Utils/utils"; interface AddICD11DiagnosisProps { @@ -29,10 +29,13 @@ export default function AddICD11Diagnosis(props: AddICD11DiagnosisProps) { const [adding, setAdding] = useState(false); const hasError = !!props.disallowed.find((d) => d?.id === selected?.id); - const { res, data, loading, refetch } = useQuery(routes.listICD11Diagnosis, { - prefetch: false, - silent: true, - }); + const { res, data, loading, refetch } = useTanStackQueryInstead( + routes.listICD11Diagnosis, + { + prefetch: false, + silent: true, + }, + ); useEffect(() => { if (res?.status === 500) { diff --git a/src/components/Facility/AddBedForm.tsx b/src/components/Facility/AddBedForm.tsx index 74b65284b02..0aa9740c26b 100644 --- a/src/components/Facility/AddBedForm.tsx +++ b/src/components/Facility/AddBedForm.tsx @@ -18,7 +18,7 @@ import { LOCATION_BED_TYPES } from "@/common/constants"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; interface Props { facilityId: string; @@ -46,14 +46,17 @@ export const AddBedForm = ({ facilityId, locationId, bedId }: Props) => { numberOfBeds: "", }); - const { data: location } = useQuery(routes.getFacilityAssetLocation, { - pathParams: { - facility_external_id: facilityId, - external_id: locationId, + const { data: location } = useTanStackQueryInstead( + routes.getFacilityAssetLocation, + { + pathParams: { + facility_external_id: facilityId, + external_id: locationId, + }, }, - }); + ); - const { data, loading } = useQuery(routes.getFacilityBed, { + const { data, loading } = useTanStackQueryInstead(routes.getFacilityBed, { pathParams: { external_id: bedId ?? "" }, prefetch: !!bedId, onResponse: ({ data }) => { diff --git a/src/components/Facility/AddInventoryForm.tsx b/src/components/Facility/AddInventoryForm.tsx index 0ab873a3cd5..0a786f1082e 100644 --- a/src/components/Facility/AddInventoryForm.tsx +++ b/src/components/Facility/AddInventoryForm.tsx @@ -14,7 +14,7 @@ import useAppHistory from "@/hooks/useAppHistory"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; const initForm = { id: "", @@ -63,28 +63,34 @@ export const AddInventoryForm = (props: any) => { const limit = 14; - const { data } = useQuery(routes.getItems, { + const { data } = useTanStackQueryInstead(routes.getItems, { query: { limit, offset, }, }); - const { data: inventory } = useQuery(routes.getInventorySummary, { - pathParams: { - facility_external_id: facilityId, + const { data: inventory } = useTanStackQueryInstead( + routes.getInventorySummary, + { + pathParams: { + facility_external_id: facilityId, + }, + query: { + limit, + offset, + }, + prefetch: facilityId !== undefined, }, - query: { - limit, - offset, - }, - prefetch: facilityId !== undefined, - }); + ); - const { data: facilityObject } = useQuery(routes.getAnyFacility, { - pathParams: { id: facilityId }, - prefetch: !!facilityId, - }); + const { data: facilityObject } = useTanStackQueryInstead( + routes.getAnyFacility, + { + pathParams: { id: facilityId }, + prefetch: !!facilityId, + }, + ); useEffect(() => { // set the default units according to the item diff --git a/src/components/Facility/AddLocationForm.tsx b/src/components/Facility/AddLocationForm.tsx index bb0039285f5..71ae8bf7dc1 100644 --- a/src/components/Facility/AddLocationForm.tsx +++ b/src/components/Facility/AddLocationForm.tsx @@ -12,7 +12,7 @@ import TextFormField from "@/components/Form/FormFields/TextFormField"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; interface Props { facilityId: string; @@ -36,7 +36,7 @@ export const AddLocationForm = ({ facilityId, locationId }: Props) => { const headerText = !locationId ? "Add Location" : "Update Location"; const buttonText = !locationId ? "Add Location" : "Update Location"; - const facilityQuery = useQuery(routes.getAnyFacility, { + const facilityQuery = useTanStackQueryInstead(routes.getAnyFacility, { pathParams: { id: facilityId }, prefetch: !locationId, onResponse: ({ data }) => { @@ -44,22 +44,25 @@ export const AddLocationForm = ({ facilityId, locationId }: Props) => { }, }); - const locationQuery = useQuery(routes.getFacilityAssetLocation, { - pathParams: { - facility_external_id: facilityId, - external_id: locationId!, + const locationQuery = useTanStackQueryInstead( + routes.getFacilityAssetLocation, + { + pathParams: { + facility_external_id: facilityId, + external_id: locationId!, + }, + prefetch: !!locationId, + onResponse: ({ data }) => { + if (!data) return; + setFacilityName(data.facility?.name ?? ""); + setName(data.name); + setLocationName(data.name); + setDescription(data.description); + setLocationType(data.location_type); + setMiddlewareAddress(data.middleware_address ?? ""); + }, }, - prefetch: !!locationId, - onResponse: ({ data }) => { - if (!data) return; - setFacilityName(data.facility?.name ?? ""); - setName(data.name); - setLocationName(data.name); - setDescription(data.description); - setLocationType(data.location_type); - setMiddlewareAddress(data.middleware_address ?? ""); - }, - }); + ); const validateForm = () => { let formValid = true; diff --git a/src/components/Facility/AssetCreate.tsx b/src/components/Facility/AssetCreate.tsx index 5c507bb0a18..79b4a8e6130 100644 --- a/src/components/Facility/AssetCreate.tsx +++ b/src/components/Facility/AssetCreate.tsx @@ -39,7 +39,7 @@ import dayjs from "@/Utils/dayjs"; import { parseQueryParams } from "@/Utils/primitives"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { dateQueryString, parsePhoneNumber } from "@/Utils/utils"; const formErrorKeys = [ @@ -171,12 +171,15 @@ const AssetCreate = (props: AssetProps) => { }); }, [generalDetailsVisible, warrantyDetailsVisible, serviceDetailsVisible]); - const locationsQuery = useQuery(routes.listFacilityAssetLocation, { - pathParams: { facility_external_id: facilityId }, - query: { limit: 1 }, - }); + const locationsQuery = useTanStackQueryInstead( + routes.listFacilityAssetLocation, + { + pathParams: { facility_external_id: facilityId }, + query: { limit: 1 }, + }, + ); - const assetQuery = useQuery(routes.getAsset, { + const assetQuery = useTanStackQueryInstead(routes.getAsset, { pathParams: { external_id: assetId! }, prefetch: !!assetId, onResponse: ({ data: asset }) => { diff --git a/src/components/Facility/BedManagement.tsx b/src/components/Facility/BedManagement.tsx index 0061a885f71..13ae5f353ff 100644 --- a/src/components/Facility/BedManagement.tsx +++ b/src/components/Facility/BedManagement.tsx @@ -19,7 +19,7 @@ import AuthorizeFor, { NonReadOnlyUsers } from "@/Utils/AuthorizeFor"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; interface BedManagementProps { facilityId: string; @@ -176,12 +176,15 @@ export const BedManagement = (props: BedManagementProps) => { const { qParams, resultsPerPage } = useFilters({ limit: 16 }); const { t } = useTranslation(); - const { data: location } = useQuery(routes.getFacilityAssetLocation, { - pathParams: { - facility_external_id: facilityId, - external_id: locationId, + const { data: location } = useTanStackQueryInstead( + routes.getFacilityAssetLocation, + { + pathParams: { + facility_external_id: facilityId, + external_id: locationId, + }, }, - }); + ); return ( { @@ -59,7 +59,7 @@ export const ConsultationFeedTab = (props: ConsultationTabProps) => { const { key, operate } = useOperateCamera(asset?.id ?? ""); - const presetsQuery = useQuery(FeedRoutes.listBedPresets, { + const presetsQuery = useTanStackQueryInstead(FeedRoutes.listBedPresets, { pathParams: { bed_id: bed?.id ?? "" }, query: { limit: 100 }, prefetch: !!bed, diff --git a/src/components/Facility/ConsultationDetails/ConsultationUpdatesTab.tsx b/src/components/Facility/ConsultationDetails/ConsultationUpdatesTab.tsx index ea7448d37b2..6d7dc282cb5 100644 --- a/src/components/Facility/ConsultationDetails/ConsultationUpdatesTab.tsx +++ b/src/components/Facility/ConsultationDetails/ConsultationUpdatesTab.tsx @@ -36,7 +36,7 @@ import { EVENTS_SORT_OPTIONS } from "@/common/constants"; import routes from "@/Utils/request/api"; import { QueryParams } from "@/Utils/request/types"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { formatDate, formatDateTime, @@ -65,7 +65,7 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => { "3xl": 23 / 11, }); - useQuery(routes.listAssetBeds, { + useTanStackQueryInstead(routes.listAssetBeds, { prefetch: !!( props.consultationData.facility && props.consultationData.current_bed?.bed_object.id diff --git a/src/components/Facility/ConsultationDetails/ConsultationVentilatorTab.tsx b/src/components/Facility/ConsultationDetails/ConsultationVentilatorTab.tsx index b26ea6e0e53..030a20d9922 100644 --- a/src/components/Facility/ConsultationDetails/ConsultationVentilatorTab.tsx +++ b/src/components/Facility/ConsultationDetails/ConsultationVentilatorTab.tsx @@ -7,19 +7,22 @@ import VentilatorTable from "@/components/Facility/Consultations/VentilatorTable import useFilters from "@/hooks/useFilters"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; export const ConsultationVentilatorTab = (props: ConsultationTabProps) => { const { consultationId } = props; const { qParams, Pagination, resultsPerPage } = useFilters({ limit: 36 }); - const { loading: isLoading, data } = useQuery(routes.getDailyReports, { - pathParams: { consultationId }, - query: { - limit: resultsPerPage, - offset: (qParams.page ? qParams.page - 1 : 0) * resultsPerPage, + const { loading: isLoading, data } = useTanStackQueryInstead( + routes.getDailyReports, + { + pathParams: { consultationId }, + query: { + limit: resultsPerPage, + offset: (qParams.page ? qParams.page - 1 : 0) * resultsPerPage, + }, }, - }); + ); if (isLoading) { return ; diff --git a/src/components/Facility/ConsultationDetails/index.tsx b/src/components/Facility/ConsultationDetails/index.tsx index 191d0156d03..11f24f92968 100644 --- a/src/components/Facility/ConsultationDetails/index.tsx +++ b/src/components/Facility/ConsultationDetails/index.tsx @@ -35,7 +35,7 @@ import { triggerGoal } from "@/Integrations/Plausible"; import { CameraFeedPermittedUserTypes } from "@/Utils/permissions"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { formatDateTime, humanizeStrings, @@ -106,7 +106,7 @@ export const ConsultationDetails = (props: any) => { const authUser = useAuthUser(); - const consultationQuery = useQuery(routes.getConsultation, { + const consultationQuery = useTanStackQueryInstead(routes.getConsultation, { pathParams: { id: consultationId }, onResponse: ({ data }) => { if (!data) { @@ -124,12 +124,12 @@ export const ConsultationDetails = (props: any) => { const consultationData = consultationQuery.data; const bedId = consultationData?.current_bed?.bed_object?.id; - const isCameraAttached = useQuery(routes.listAssetBeds, { + const isCameraAttached = useTanStackQueryInstead(routes.listAssetBeds, { prefetch: !!bedId, query: { bed: bedId }, }).data?.results.some((a) => a.asset_object.asset_class === "ONVIF"); - const patientDataQuery = useQuery(routes.getPatient, { + const patientDataQuery = useTanStackQueryInstead(routes.getPatient, { pathParams: { id: consultationQuery.data?.patient ?? "" }, prefetch: !!consultationQuery.data?.patient, onResponse: ({ data }) => { diff --git a/src/components/Facility/ConsultationDoctorNotes/index.tsx b/src/components/Facility/ConsultationDoctorNotes/index.tsx index 098a4b392e3..c1f3dc43072 100644 --- a/src/components/Facility/ConsultationDoctorNotes/index.tsx +++ b/src/components/Facility/ConsultationDoctorNotes/index.tsx @@ -23,7 +23,7 @@ import { NonReadOnlyUsers } from "@/Utils/AuthorizeFor"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { classNames, isAppleDevice, keysOf } from "@/Utils/utils"; interface ConsultationDoctorNotesProps { @@ -90,7 +90,7 @@ const ConsultationDoctorNotes = (props: ConsultationDoctorNotesProps) => { } }; - useQuery(routes.getPatient, { + useTanStackQueryInstead(routes.getPatient, { pathParams: { id: patientId }, onResponse: ({ data }) => { if (data) { diff --git a/src/components/Facility/ConsultationForm.tsx b/src/components/Facility/ConsultationForm.tsx index d6d94593049..96c4fcea681 100644 --- a/src/components/Facility/ConsultationForm.tsx +++ b/src/components/Facility/ConsultationForm.tsx @@ -1,7 +1,7 @@ import careConfig from "@careConfig"; import { t } from "i18next"; import { navigate } from "raviger"; -import { LegacyRef, createRef, useEffect, useRef, useState } from "react"; +import { LegacyRef, createRef, useEffect, useState } from "react"; import CareIcon from "@/CAREUI/icons/CareIcon"; @@ -71,7 +71,7 @@ import * as Notification from "@/Utils/Notifications"; import dayjs from "@/Utils/dayjs"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { Writable } from "@/Utils/types"; import { classNames } from "@/Utils/utils"; @@ -235,7 +235,6 @@ type Props = { export const ConsultationForm = ({ facilityId, patientId, id }: Props) => { const { goBack } = useAppHistory(); - const submitController = useRef(); const [state, dispatch] = useAutoSaveReducer( consultationFormReducer, initialState, @@ -298,21 +297,24 @@ export const ConsultationForm = ({ facilityId, patientId, id }: Props) => { bedStatusVisible, ]); - const { loading: loadingPatient } = useQuery(routes.getPatient, { - pathParams: { id: patientId }, - onResponse: ({ data }) => { - if (!data) return; - if (isUpdate) { - dispatch({ - type: "set_form", - form: { ...state.form, action: data.action }, - }); - } - setPatientName(data.name ?? ""); - setFacilityName(data.facility_object?.name ?? ""); + const { loading: loadingPatient } = useTanStackQueryInstead( + routes.getPatient, + { + pathParams: { id: patientId }, + onResponse: ({ data }) => { + if (!data) return; + if (isUpdate) { + dispatch({ + type: "set_form", + form: { ...state.form, action: data.action }, + }); + } + setPatientName(data.name ?? ""); + setFacilityName(data.facility_object?.name ?? ""); + }, + prefetch: !!patientId, }, - prefetch: !!patientId, - }); + ); useEffect(() => { dispatch({ @@ -348,7 +350,7 @@ export const ConsultationForm = ({ facilityId, patientId, id }: Props) => { }); }; - const { loading: consultationLoading, refetch } = useQuery( + const { loading: consultationLoading, refetch } = useTanStackQueryInstead( routes.getConsultation, { pathParams: { id: id! }, @@ -741,7 +743,6 @@ export const ConsultationForm = ({ facilityId, patientId, id }: Props) => { { pathParams: id ? { id } : undefined, body: data, - controllerRef: submitController, }, ); diff --git a/src/components/Facility/Consultations/Beds.tsx b/src/components/Facility/Consultations/Beds.tsx index 38d905b8349..7d68fcb49c5 100644 --- a/src/components/Facility/Consultations/Beds.tsx +++ b/src/components/Facility/Consultations/Beds.tsx @@ -24,7 +24,7 @@ import * as Notification from "@/Utils/Notifications"; import dayjs from "@/Utils/dayjs"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; interface BedsProps { facilityId: string; @@ -47,7 +47,7 @@ const Beds = (props: BedsProps) => { const [key, setKey] = useState(0); const [showBedDetails, setShowBedDetails] = useState(null); - const { loading } = useQuery(routes.listConsultationBeds, { + const { loading } = useTanStackQueryInstead(routes.listConsultationBeds, { query: { consultation: consultationId }, onResponse: ({ res, data }) => { if (res && res.status === 200 && data?.results) { diff --git a/src/components/Facility/DischargeModal.tsx b/src/components/Facility/DischargeModal.tsx index 07229c9e17a..be71997aa43 100644 --- a/src/components/Facility/DischargeModal.tsx +++ b/src/components/Facility/DischargeModal.tsx @@ -29,7 +29,7 @@ import * as Notification from "@/Utils/Notifications"; import dayjs from "@/Utils/dayjs"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; interface PreDischargeFormInterface { new_discharge_reason: number | null; @@ -92,7 +92,7 @@ const DischargeModal = ({ setFacility(referred_to); }, [referred_to]); - const initialDiagnoses = useQuery(routes.getConsultation, { + const initialDiagnoses = useTanStackQueryInstead(routes.getConsultation, { pathParams: { id: consultationData.id ?? "" }, prefetch: !!consultationData.id, }).data?.diagnoses; diff --git a/src/components/Facility/DischargedPatientsList.tsx b/src/components/Facility/DischargedPatientsList.tsx index b489a799b1d..4fb8910f7a1 100644 --- a/src/components/Facility/DischargedPatientsList.tsx +++ b/src/components/Facility/DischargedPatientsList.tsx @@ -39,7 +39,7 @@ import { import { parseOptionId } from "@/common/utils"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { formatPatientAge, humanizeStrings } from "@/Utils/utils"; const DischargedPatientsList = ({ @@ -48,7 +48,7 @@ const DischargedPatientsList = ({ facility_external_id: string; }) => { const { t } = useTranslation(); - const facilityQuery = useQuery(routes.getAnyFacility, { + const facilityQuery = useTanStackQueryInstead(routes.getAnyFacility, { pathParams: { id: facility_external_id }, }); @@ -75,21 +75,21 @@ const DischargedPatientsList = ({ } }, [qParams]); - const { data: districtData } = useQuery(routes.getDistrict, { + const { data: districtData } = useTanStackQueryInstead(routes.getDistrict, { pathParams: { id: qParams.district, }, prefetch: !!Number(qParams.district), }); - const { data: LocalBodyData } = useQuery(routes.getLocalBody, { + const { data: LocalBodyData } = useTanStackQueryInstead(routes.getLocalBody, { pathParams: { id: qParams.lsgBody, }, prefetch: !!Number(qParams.lsgBody), }); - const { data: facilityAssetLocationData } = useQuery( + const { data: facilityAssetLocationData } = useTanStackQueryInstead( routes.getFacilityAssetLocation, { pathParams: { diff --git a/src/components/Facility/DoctorVideoSlideover.tsx b/src/components/Facility/DoctorVideoSlideover.tsx index 73349624780..61c7a63c17b 100644 --- a/src/components/Facility/DoctorVideoSlideover.tsx +++ b/src/components/Facility/DoctorVideoSlideover.tsx @@ -14,7 +14,7 @@ import { triggerGoal } from "@/Integrations/Plausible"; import { PLUGIN_Component } from "@/PluginEngine"; import { Warn } from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { classNames, formatName, @@ -55,7 +55,7 @@ export default function DoctorVideoSlideover(props: { const { show, facilityId, setShow } = props; const [filter, setFilter] = useState("ALL"); - const { data } = useQuery(routes.getFacilityUsers, { + const { data } = useTanStackQueryInstead(routes.getFacilityUsers, { prefetch: show, pathParams: { facility_id: facilityId }, query: { limit: 50 }, diff --git a/src/components/Facility/FacilityBedCapacity.tsx b/src/components/Facility/FacilityBedCapacity.tsx index 2c1c164c04b..cf0ac28a24a 100644 --- a/src/components/Facility/FacilityBedCapacity.tsx +++ b/src/components/Facility/FacilityBedCapacity.tsx @@ -12,14 +12,14 @@ import { BED_TYPES } from "@/common/constants"; import { NonReadOnlyUsers } from "@/Utils/AuthorizeFor"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; export const FacilityBedCapacity = (props: any) => { const { t } = useTranslation(); const [bedCapacityModalOpen, setBedCapacityModalOpen] = useState(false); - const capacityQuery = useQuery(routes.getCapacity, { + const capacityQuery = useTanStackQueryInstead(routes.getCapacity, { pathParams: { facilityId: props.facilityId }, }); diff --git a/src/components/Facility/FacilityConfigure.tsx b/src/components/Facility/FacilityConfigure.tsx index 1cb7c7d69cf..4579c450584 100644 --- a/src/components/Facility/FacilityConfigure.tsx +++ b/src/components/Facility/FacilityConfigure.tsx @@ -12,7 +12,7 @@ import { PLUGIN_Component } from "@/PluginEngine"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; const initForm = { name: "", @@ -56,7 +56,7 @@ export const FacilityConfigure = (props: IProps) => { const { facilityId } = props; const [isLoading, setIsLoading] = useState(false); - const { loading } = useQuery(routes.getPermittedFacility, { + const { loading } = useTanStackQueryInstead(routes.getPermittedFacility, { pathParams: { id: facilityId }, onResponse: (res) => { if (res.data) { diff --git a/src/components/Facility/FacilityCreate.tsx b/src/components/Facility/FacilityCreate.tsx index d0548e15769..37b98492c6f 100644 --- a/src/components/Facility/FacilityCreate.tsx +++ b/src/components/Facility/FacilityCreate.tsx @@ -60,7 +60,7 @@ import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; import { RequestResult } from "@/Utils/request/types"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { compareBy, getPincodeDetails, @@ -185,22 +185,20 @@ export const FacilityCreate = (props: FacilityProps) => { data: districtData, refetch: districtFetch, loading: isDistrictLoading, - } = useQuery(routes.getDistrictByState, { + } = useTanStackQueryInstead(routes.getDistrictByState, { pathParams: { id: String(stateId), }, prefetch: !!stateId, }); - const { data: localbodyData, loading: isLocalbodyLoading } = useQuery( - routes.getLocalbodyByDistrict, - { + const { data: localbodyData, loading: isLocalbodyLoading } = + useTanStackQueryInstead(routes.getLocalbodyByDistrict, { pathParams: { id: String(districtId), }, prefetch: !!districtId, - }, - ); + }); const getSteps = (): Step[] => { return [ @@ -239,7 +237,7 @@ export const FacilityCreate = (props: FacilityProps) => { ]; }; - const { data: wardData, loading: isWardLoading } = useQuery( + const { data: wardData, loading: isWardLoading } = useTanStackQueryInstead( routes.getWardByLocalBody, { pathParams: { @@ -249,7 +247,7 @@ export const FacilityCreate = (props: FacilityProps) => { }, ); - const facilityQuery = useQuery(routes.getPermittedFacility, { + const facilityQuery = useTanStackQueryInstead(routes.getPermittedFacility, { pathParams: { id: facilityId!, }, @@ -299,7 +297,7 @@ export const FacilityCreate = (props: FacilityProps) => { }, }); - const { data: stateData, loading: isStateLoading } = useQuery( + const { data: stateData, loading: isStateLoading } = useTanStackQueryInstead( routes.statesList, ); diff --git a/src/components/Facility/FacilityHome.tsx b/src/components/Facility/FacilityHome.tsx index e38c187590e..cf671a51530 100644 --- a/src/components/Facility/FacilityHome.tsx +++ b/src/components/Facility/FacilityHome.tsx @@ -45,7 +45,7 @@ import { CameraFeedPermittedUserTypes } from "@/Utils/permissions"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; import uploadFile from "@/Utils/request/uploadFile"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { sleep } from "@/Utils/utils"; import { patientRegisterAuth } from "../Patient/PatientRegister"; @@ -73,7 +73,7 @@ export const FacilityHome = ({ facilityId }: Props) => { data: facilityData, loading: isLoading, refetch: facilityFetch, - } = useQuery(routes.getPermittedFacility, { + } = useTanStackQueryInstead(routes.getPermittedFacility, { pathParams: { id: facilityId, }, @@ -84,14 +84,14 @@ export const FacilityHome = ({ facilityId }: Props) => { }, }); - const spokesQuery = useQuery(routes.getFacilitySpokes, { + const spokesQuery = useTanStackQueryInstead(routes.getFacilitySpokes, { pathParams: { id: facilityId, }, silent: true, }); - const hubsQuery = useQuery(routes.getFacilityHubs, { + const hubsQuery = useTanStackQueryInstead(routes.getFacilityHubs, { pathParams: { id: facilityId, }, @@ -525,10 +525,7 @@ export const FacilityHome = ({ facilityId }: Props) => { - + ); }; diff --git a/src/components/Facility/FacilityHomeTriage.tsx b/src/components/Facility/FacilityHomeTriage.tsx index 7349ccfcb38..25d2e0a7334 100644 --- a/src/components/Facility/FacilityHomeTriage.tsx +++ b/src/components/Facility/FacilityHomeTriage.tsx @@ -5,51 +5,49 @@ import CareIcon from "@/CAREUI/icons/CareIcon"; import ButtonV2 from "@/components/Common/ButtonV2"; import Table from "@/components/Common/Table"; +import { NonReadOnlyUsers } from "@/Utils/AuthorizeFor"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; -export const FacilityHomeTriage = (props: any) => { - const triageQuery = useQuery(routes.getTriage, { - pathParams: { facilityId: props.facilityId }, +interface FacilityHomeTriageProps { + facilityId: string; +} + +export function FacilityHomeTriage({ facilityId }: FacilityHomeTriageProps) { + const { data } = useTanStackQueryInstead(routes.getTriage, { + pathParams: { facilityId }, }); - const stats: (string | JSX.Element)[][] = []; - for ( - let i = 0; - triageQuery.data?.results && i < triageQuery.data.results.length; - i++ - ) { - const temp: (string | JSX.Element)[] = []; - temp.push(String(triageQuery.data.results[i].entry_date) || "0"); - temp.push(String(triageQuery.data.results[i].num_patients_visited) || "0"); - temp.push( - String(triageQuery.data.results[i].num_patients_home_quarantine) || "0", - ); - temp.push( - String(triageQuery.data.results[i].num_patients_isolation) || "0", - ); - temp.push(String(triageQuery.data.results[i].num_patient_referred) || "0"); - temp.push( - String(triageQuery.data.results[i].num_patient_confirmed_positive) || "0", - ); - temp.push( + const tableRows = + data?.results?.map((result) => [ + String(result.entry_date), + String(result.num_patients_visited), + String(result.num_patients_home_quarantine), + String(result.num_patients_isolation), + String(result.num_patient_referred), + String(result.num_patient_confirmed_positive), - navigate( - `/facility/${props.facilityId}/triage/${triageQuery.data?.results[i].id}`, - ) - } - authorizeFor={props.NonReadOnlyUsers} + onClick={() => navigate(`/facility/${facilityId}/triage/${result.id}`)} + authorizeFor={NonReadOnlyUsers} > Edit , - ); - stats.push(temp); - } + ]) ?? []; + + const tableHeadings = [ + "Date", + "Total Triaged", + "Advised Home Quarantine", + "Suspects Isolated", + "Referred", + "Confirmed positives", + "Actions", + ]; return (
@@ -59,8 +57,8 @@ export const FacilityHomeTriage = (props: any) => { navigate(`/facility/${props.facilityId}/triage`)} - authorizeFor={props.NonReadOnlyUsers} + onClick={() => navigate(`/facility/${facilityId}/triage`)} + authorizeFor={NonReadOnlyUsers} > { Add Triage
+
- - {stats.length === 0 && ( +
+ + {tableRows.length === 0 && ( <>
@@ -97,4 +86,4 @@ export const FacilityHomeTriage = (props: any) => {
); -}; +} diff --git a/src/components/Facility/FacilityList.tsx b/src/components/Facility/FacilityList.tsx index 164632e1601..0c1164649ca 100644 --- a/src/components/Facility/FacilityList.tsx +++ b/src/components/Facility/FacilityList.tsx @@ -19,7 +19,7 @@ import useFilters from "@/hooks/useFilters"; import { FACILITY_TYPES } from "@/common/constants"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import SearchByMultipleFields from "../Common/SearchByMultipleFields"; @@ -50,7 +50,7 @@ export const FacilityList = () => { const { user_type } = useAuthUser(); const { t } = useTranslation(); - const { data: permittedData, loading: isLoading } = useQuery( + const { data: permittedData, loading: isLoading } = useTanStackQueryInstead( routes.getPermittedFacilities, { query: { @@ -67,21 +67,21 @@ export const FacilityList = () => { }, ); - const { data: stateData } = useQuery(routes.getState, { + const { data: stateData } = useTanStackQueryInstead(routes.getState, { pathParams: { id: qParams.state, }, prefetch: qParams.state !== undefined, }); - const { data: districtData } = useQuery(routes.getDistrict, { + const { data: districtData } = useTanStackQueryInstead(routes.getDistrict, { pathParams: { id: qParams.district, }, prefetch: qParams.district !== undefined, }); - const { data: localBodyData } = useQuery(routes.getLocalBody, { + const { data: localBodyData } = useTanStackQueryInstead(routes.getLocalBody, { pathParams: { id: qParams.local_body, }, diff --git a/src/components/Facility/FacilityStaffList.tsx b/src/components/Facility/FacilityStaffList.tsx index e7a2ea08f10..5a3cd512ba9 100644 --- a/src/components/Facility/FacilityStaffList.tsx +++ b/src/components/Facility/FacilityStaffList.tsx @@ -17,7 +17,7 @@ import { DOCTOR_SPECIALIZATION } from "@/common/constants"; import { NonReadOnlyUsers } from "@/Utils/AuthorizeFor"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; export const FacilityStaffList = (props: any) => { const { t } = useTranslation(); @@ -25,24 +25,27 @@ export const FacilityStaffList = (props: any) => { const { qParams, resultsPerPage, updatePage } = useFilters({ limit: 15 }); const [totalDoctors, setTotalDoctors] = useState(0); - const { data: doctorsList, refetch } = useQuery(routes.listDoctor, { - pathParams: { facilityId: props.facilityId }, - query: { - limit: resultsPerPage, - offset: (qParams.page - 1) * resultsPerPage, + const { data: doctorsList, refetch } = useTanStackQueryInstead( + routes.listDoctor, + { + pathParams: { facilityId: props.facilityId }, + query: { + limit: resultsPerPage, + offset: (qParams.page - 1) * resultsPerPage, + }, + onResponse: ({ res, data }) => { + if (res?.ok && data) { + let totalCount = 0; + data.results.map((doctor: DoctorModal) => { + if (doctor.count) { + totalCount += doctor.count; + } + }); + setTotalDoctors(totalCount); + } + }, }, - onResponse: ({ res, data }) => { - if (res?.ok && data) { - let totalCount = 0; - data.results.map((doctor: DoctorModal) => { - if (doctor.count) { - totalCount += doctor.count; - } - }); - setTotalDoctors(totalCount); - } - }, - }); + ); let doctorList: any = null; if (!doctorsList || !doctorsList.results.length) { diff --git a/src/components/Facility/FacilityUsers.tsx b/src/components/Facility/FacilityUsers.tsx index 3adaf0fb083..aeb9187a4cd 100644 --- a/src/components/Facility/FacilityUsers.tsx +++ b/src/components/Facility/FacilityUsers.tsx @@ -9,7 +9,7 @@ import UserListView from "@/components/Users/UserListAndCard"; import useFilters from "@/hooks/useFilters"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; export default function FacilityUsers(props: { facilityId: number }) { const { t } = useTranslation(); @@ -20,16 +20,18 @@ export default function FacilityUsers(props: { facilityId: number }) { const [activeTab, setActiveTab] = useState(0); const { facilityId } = props; - const { data: facilityData } = useQuery(routes.getAnyFacility, { - pathParams: { - id: facilityId, + const { data: facilityData } = useTanStackQueryInstead( + routes.getAnyFacility, + { + pathParams: { + id: facilityId, + }, + prefetch: facilityId !== undefined, }, - prefetch: facilityId !== undefined, - }); + ); - const { data: userListData, loading: userListLoading } = useQuery( - routes.getFacilityUsers, - { + const { data: userListData, loading: userListLoading } = + useTanStackQueryInstead(routes.getFacilityUsers, { query: { limit: resultsPerPage, offset: ( @@ -39,8 +41,7 @@ export default function FacilityUsers(props: { facilityId: number }) { }, pathParams: { facility_id: facilityId }, prefetch: facilityId !== undefined, - }, - ); + }); return ( { const offset = (page - 1) * limit; diff --git a/src/components/Facility/InventoryLog.tsx b/src/components/Facility/InventoryLog.tsx index abd8532d953..20a3feb67b8 100644 --- a/src/components/Facility/InventoryLog.tsx +++ b/src/components/Facility/InventoryLog.tsx @@ -10,7 +10,7 @@ import Pagination from "@/components/Common/Pagination"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { formatDateTime } from "@/Utils/utils"; export default function InventoryLog(props: any) { @@ -22,7 +22,7 @@ export default function InventoryLog(props: any) { const limit = 14; const item = inventoryId; - const { data, refetch } = useQuery(routes.getInventoryLog, { + const { data, refetch } = useTanStackQueryInstead(routes.getInventoryLog, { pathParams: { facilityId: facilityId, }, @@ -34,10 +34,13 @@ export default function InventoryLog(props: any) { prefetch: facilityId !== undefined, }); - const { data: facilityObject } = useQuery(routes.getAnyFacility, { - pathParams: { id: facilityId }, - prefetch: !!facilityId, - }); + const { data: facilityObject } = useTanStackQueryInstead( + routes.getAnyFacility, + { + pathParams: { id: facilityId }, + prefetch: !!facilityId, + }, + ); const flagFacility = async (id: string) => { setSaving(true); diff --git a/src/components/Facility/Investigations/InvestigationSuggestions.tsx b/src/components/Facility/Investigations/InvestigationSuggestions.tsx index 0593a49e8a2..c793450a48c 100644 --- a/src/components/Facility/Investigations/InvestigationSuggestions.tsx +++ b/src/components/Facility/Investigations/InvestigationSuggestions.tsx @@ -8,7 +8,7 @@ import { InvestigationResponse } from "@/components/Facility/Investigations/Repo import dayjs from "@/Utils/dayjs"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; export default function ViewInvestigationSuggestions(props: { consultationId: string; @@ -22,11 +22,14 @@ export default function ViewInvestigationSuggestions(props: { investigations: previousInvestigations, } = props; - const { data: investigations, loading } = useQuery(routes.getConsultation, { - pathParams: { - id: consultationId, + const { data: investigations, loading } = useTanStackQueryInstead( + routes.getConsultation, + { + pathParams: { + id: consultationId, + }, }, - }); + ); if (loading) { return ; diff --git a/src/components/Facility/Investigations/InvestigationsPrintPreview.tsx b/src/components/Facility/Investigations/InvestigationsPrintPreview.tsx index 3c37cd42801..3b68f09c676 100644 --- a/src/components/Facility/Investigations/InvestigationsPrintPreview.tsx +++ b/src/components/Facility/Investigations/InvestigationsPrintPreview.tsx @@ -7,7 +7,7 @@ import PrintPreview from "@/CAREUI/misc/PrintPreview"; import { Investigation } from "@/components/Facility/Investigations/Reports/types"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; const Loading = lazy(() => import("@/components/Common/Loading")); @@ -94,29 +94,30 @@ export default function InvestigationPrintPreview( ) { const { consultationId, patientId, sessionId } = props; const { t } = useTranslation(); - const { loading: investigationLoading, data: investigations } = useQuery( - routes.getInvestigation, - { + const { loading: investigationLoading, data: investigations } = + useTanStackQueryInstead(routes.getInvestigation, { pathParams: { consultation_external_id: consultationId, }, query: { session: sessionId, }, - }, - ); + }); - const { data: patient, loading: patientLoading } = useQuery( + const { data: patient, loading: patientLoading } = useTanStackQueryInstead( routes.getPatient, { pathParams: { id: patientId }, }, ); - const { data: consultation } = useQuery(routes.getConsultation, { - pathParams: { id: consultationId }, - prefetch: !!consultationId, - }); + const { data: consultation } = useTanStackQueryInstead( + routes.getConsultation, + { + pathParams: { id: consultationId }, + prefetch: !!consultationId, + }, + ); if (patientLoading || investigationLoading) { return ; diff --git a/src/components/Facility/Investigations/Reports/index.tsx b/src/components/Facility/Investigations/Reports/index.tsx index 32f0abcb7bc..f1b27d422d9 100644 --- a/src/components/Facility/Investigations/Reports/index.tsx +++ b/src/components/Facility/Investigations/Reports/index.tsx @@ -21,7 +21,7 @@ import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; import { PaginatedResponse } from "@/Utils/request/types"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { formatPatientAge } from "@/Utils/utils"; const RESULT_PER_PAGE = 14; @@ -196,7 +196,7 @@ const InvestigationReports = ({ id }: any) => { }); }, [isLoading, selectedGroup]); - useQuery(routes.listInvestigationGroups, { + useTanStackQueryInstead(routes.listInvestigationGroups, { onResponse: (res) => { if (res && res.data) { dispatch({ @@ -207,12 +207,10 @@ const InvestigationReports = ({ id }: any) => { }, }); - const { data: patientData, loading: patientLoading } = useQuery( - routes.getPatient, - { + const { data: patientData, loading: patientLoading } = + useTanStackQueryInstead(routes.getPatient, { pathParams: { id: id }, - }, - ); + }); const handleGroupSelect = ({ value }: FieldChangeEvent) => { dispatch({ type: "set_investigations", payload: [] }); diff --git a/src/components/Facility/Investigations/ShowInvestigation.tsx b/src/components/Facility/Investigations/ShowInvestigation.tsx index 05f2dd8eecf..01c59c83aad 100644 --- a/src/components/Facility/Investigations/ShowInvestigation.tsx +++ b/src/components/Facility/Investigations/ShowInvestigation.tsx @@ -8,7 +8,7 @@ import InvestigationTable from "@/components/Facility/Investigations/Investigati import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; // import { setNestedValueSafely } from "@/Utils/utils"; @@ -46,51 +46,58 @@ export default function ShowInvestigation(props: ShowInvestigationProps) { const { consultationId, patientId, sessionId, facilityId } = props; const { t } = useTranslation(); const [state, dispatch] = useReducer(updateFormReducer, initialState); - const { loading: investigationLoading } = useQuery(routes.getInvestigation, { - pathParams: { - consultation_external_id: consultationId, - }, - query: { - session: sessionId, + const { loading: investigationLoading } = useTanStackQueryInstead( + routes.getInvestigation, + { + pathParams: { + consultation_external_id: consultationId, + }, + query: { + session: sessionId, + }, + onResponse: (res) => { + if (res && res.data) { + const valueMap = res.data.results.reduce( + (acc: any, cur: { id: any }) => ({ ...acc, [cur.id]: cur }), + {}, + ); + + const changedValues = res.data.results.reduce( + (acc: any, cur: any) => ({ + ...acc, + [cur.id]: { + id: cur?.id, + initialValue: cur?.notes || cur?.value || null, + value: cur?.value || null, + notes: cur?.notes || null, + }, + }), + {}, + ); + + dispatch({ type: "set_initial_values", initialValues: valueMap }); + dispatch({ + type: "set_changed_fields", + changedFields: changedValues, + }); + } + }, }, - onResponse: (res) => { - if (res && res.data) { - const valueMap = res.data.results.reduce( - (acc: any, cur: { id: any }) => ({ ...acc, [cur.id]: cur }), - {}, - ); - - const changedValues = res.data.results.reduce( - (acc: any, cur: any) => ({ - ...acc, - [cur.id]: { - id: cur?.id, - initialValue: cur?.notes || cur?.value || null, - value: cur?.value || null, - notes: cur?.notes || null, - }, - }), - {}, - ); + ); - dispatch({ type: "set_initial_values", initialValues: valueMap }); - dispatch({ type: "set_changed_fields", changedFields: changedValues }); - } - }, - }); + const { data: patientData, loading: patientLoading } = + useTanStackQueryInstead(routes.getPatient, { + pathParams: { id: patientId }, + }); - const { data: patientData, loading: patientLoading } = useQuery( - routes.getPatient, + const { data: consultation } = useTanStackQueryInstead( + routes.getConsultation, { - pathParams: { id: patientId }, + pathParams: { id: consultationId }, + prefetch: !!consultationId, }, ); - const { data: consultation } = useQuery(routes.getConsultation, { - pathParams: { id: consultationId }, - prefetch: !!consultationId, - }); - const handleValueChange = (value: any, name: string) => { const keys = name.split("."); // Validate keys to prevent prototype pollution - coderabbit suggested diff --git a/src/components/Facility/Investigations/index.tsx b/src/components/Facility/Investigations/index.tsx index 41266e5b848..da5d93e7ea9 100644 --- a/src/components/Facility/Investigations/index.tsx +++ b/src/components/Facility/Investigations/index.tsx @@ -13,7 +13,7 @@ import AutocompleteMultiSelectFormField from "@/components/Form/FormFields/Autoc import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; const initialState = { form: {}, @@ -109,24 +109,22 @@ const Investigation = (props: { const [selectedItems, selectItems] = useState([]); const { data: investigations, loading: listInvestigationDataLoading } = - useQuery(routes.listInvestigations, {}); + useTanStackQueryInstead(routes.listInvestigations, {}); const { data: investigationGroups, loading: listInvestigationGroupDataLoading, - } = useQuery(routes.listInvestigationGroups, {}); + } = useTanStackQueryInstead(routes.listInvestigationGroups, {}); - const { data: patientData, loading: patientLoading } = useQuery( - routes.getPatient, - { + const { data: patientData, loading: patientLoading } = + useTanStackQueryInstead(routes.getPatient, { pathParams: { id: patientId }, onResponse: (res) => { if (res.data) { setSession(new Date().toString()); } }, - }, - ); + }); useEffect(() => { if ( diff --git a/src/components/Facility/Investigations/investigationsTab.tsx b/src/components/Facility/Investigations/investigationsTab.tsx index d6abba46f55..1bc4c62011d 100644 --- a/src/components/Facility/Investigations/investigationsTab.tsx +++ b/src/components/Facility/Investigations/investigationsTab.tsx @@ -3,7 +3,7 @@ import ViewInvestigations from "@/components/Facility/Investigations/ViewInvesti import { PatientModel } from "@/components/Patient/models"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; export interface InvestigationSessionType { session_external_id: string; @@ -17,17 +17,15 @@ export default function InvestigationTab(props: { patientData: PatientModel; }) { const { consultationId, patientId, facilityId, patientData } = props; - const { data: investigations, loading: investigationLoading } = useQuery( - routes.getInvestigation, - { + const { data: investigations, loading: investigationLoading } = + useTanStackQueryInstead(routes.getInvestigation, { pathParams: { consultation_external_id: consultationId, }, - }, - ); + }); const { data: investigationSessions, loading: investigationSessionLoading } = - useQuery(routes.getInvestigationSessions, { + useTanStackQueryInstead(routes.getInvestigationSessions, { pathParams: { consultation_external_id: consultationId, }, diff --git a/src/components/Facility/LocationManagement.tsx b/src/components/Facility/LocationManagement.tsx index 2f80a879651..c977fce8ff6 100644 --- a/src/components/Facility/LocationManagement.tsx +++ b/src/components/Facility/LocationManagement.tsx @@ -18,7 +18,7 @@ import AuthorizeFor, { NonReadOnlyUsers } from "@/Utils/AuthorizeFor"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; interface Props { facilityId: string; @@ -229,7 +229,7 @@ const Location = ({ setShowDeletePopup, facilityId, }: LocationProps) => { - const bedsQuery = useQuery(routes.listFacilityBeds, { + const bedsQuery = useTanStackQueryInstead(routes.listFacilityBeds, { query: { facility: facilityId, location: id, diff --git a/src/components/Facility/MinQuantityList.tsx b/src/components/Facility/MinQuantityList.tsx index 32ec4a9f8c1..eb0e69a08d5 100644 --- a/src/components/Facility/MinQuantityList.tsx +++ b/src/components/Facility/MinQuantityList.tsx @@ -8,7 +8,7 @@ import { MinQuantityRequiredModal } from "@/components/Facility/MinQuantityRequi import { NonReadOnlyUsers } from "@/Utils/AuthorizeFor"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; export default function MinQuantityList(props: any) { const { facilityId }: any = props; @@ -20,9 +20,8 @@ export default function MinQuantityList(props: any) { const [selectedItem, setSelectedItem] = useState({ id: 0, item_id: 0 }); const limit = 14; - const { data: minimumQuantityData, refetch: minimumQuantityfetch } = useQuery( - routes.getMinQuantity, - { + const { data: minimumQuantityData, refetch: minimumQuantityfetch } = + useTanStackQueryInstead(routes.getMinQuantity, { pathParams: { facilityId, }, @@ -31,14 +30,16 @@ export default function MinQuantityList(props: any) { offset, }, prefetch: !!facilityId, + }); + + const { data: facilityObject } = useTanStackQueryInstead( + routes.getAnyFacility, + { + pathParams: { id: facilityId }, + prefetch: !!facilityId, }, ); - const { data: facilityObject } = useQuery(routes.getAnyFacility, { - pathParams: { id: facilityId }, - prefetch: !!facilityId, - }); - const handlePagination = (page: number, limit: number) => { const offset = (page - 1) * limit; setCurrentPage(page); diff --git a/src/components/Facility/MinQuantityRequiredModal.tsx b/src/components/Facility/MinQuantityRequiredModal.tsx index 8fc3f7abd47..644c7b19ebd 100644 --- a/src/components/Facility/MinQuantityRequiredModal.tsx +++ b/src/components/Facility/MinQuantityRequiredModal.tsx @@ -7,7 +7,7 @@ import TextFormField from "@/components/Form/FormFields/TextFormField"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; const initForm = { id: "", @@ -42,7 +42,7 @@ export const MinQuantityRequiredModal = (props: any) => { props; const [isLoading, setIsLoading] = useState(true); - const { data: minimumQuantityItemData } = useQuery( + const { data: minimumQuantityItemData } = useTanStackQueryInstead( routes.getMinQuantityItem, { pathParams: { @@ -61,10 +61,13 @@ export const MinQuantityRequiredModal = (props: any) => { }, ); - const { data: facilityObject } = useQuery(routes.getAnyFacility, { - pathParams: { id: facilityId }, - prefetch: !!facilityId, - }); + const { data: facilityObject } = useTanStackQueryInstead( + routes.getAnyFacility, + { + pathParams: { id: facilityId }, + prefetch: !!facilityId, + }, + ); const handleSubmit = async (e: any) => { e.preventDefault(); diff --git a/src/components/Facility/SetInventoryForm.tsx b/src/components/Facility/SetInventoryForm.tsx index 9c401eab0bd..ccaf60ef731 100644 --- a/src/components/Facility/SetInventoryForm.tsx +++ b/src/components/Facility/SetInventoryForm.tsx @@ -14,7 +14,7 @@ import useAppHistory from "@/hooks/useAppHistory"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; const initForm = { id: "", @@ -58,7 +58,7 @@ export const SetInventoryForm = (props: any) => { const limit = 14; const offset = 0; - useQuery(routes.getMinQuantity, { + useTanStackQueryInstead(routes.getMinQuantity, { pathParams: { facilityId, }, @@ -91,10 +91,13 @@ export const SetInventoryForm = (props: any) => { }, }); - const { data: facilityObject } = useQuery(routes.getAnyFacility, { - pathParams: { id: facilityId }, - prefetch: !!facilityId, - }); + const { data: facilityObject } = useTanStackQueryInstead( + routes.getAnyFacility, + { + pathParams: { id: facilityId }, + prefetch: !!facilityId, + }, + ); useEffect(() => { // set the default units according to the item diff --git a/src/components/Facility/SpokeFacilityEditor.tsx b/src/components/Facility/SpokeFacilityEditor.tsx index 124e31a375a..9d8364395f2 100644 --- a/src/components/Facility/SpokeFacilityEditor.tsx +++ b/src/components/Facility/SpokeFacilityEditor.tsx @@ -17,7 +17,7 @@ import { SPOKE_RELATION_TYPES } from "@/common/constants"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; export interface SpokeFacilityEditorProps { facility: Omit & { id: string }; @@ -28,7 +28,7 @@ export default function SpokeFacilityEditor(props: SpokeFacilityEditorProps) { const { t } = useTranslation(); - const spokesQuery = useQuery(routes.getFacilitySpokes, { + const spokesQuery = useTanStackQueryInstead(routes.getFacilitySpokes, { pathParams: { id: facility.id, }, diff --git a/src/components/Facility/StaffCapacity.tsx b/src/components/Facility/StaffCapacity.tsx index 6afef52e014..53235dd68d0 100644 --- a/src/components/Facility/StaffCapacity.tsx +++ b/src/components/Facility/StaffCapacity.tsx @@ -16,7 +16,7 @@ import { DOCTOR_SPECIALIZATION } from "@/common/constants"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; interface DoctorCapacityProps extends DoctorModal { facilityId: string; @@ -70,14 +70,14 @@ export const StaffCapacity = (props: DoctorCapacityProps) => { const [state, dispatch] = useReducer(doctorCapacityReducer, initialState); const [isLoading, setIsLoading] = useState(false); - const specializationsQuery = useQuery(routes.listDoctor, { + const specializationsQuery = useTanStackQueryInstead(routes.listDoctor, { pathParams: { facilityId }, query: { limit: DOCTOR_SPECIALIZATION.length - 1, }, }); - const { loading } = useQuery(routes.getDoctor, { + const { loading } = useTanStackQueryInstead(routes.getDoctor, { pathParams: { facilityId, id: `${id}` }, prefetch: !!id, onResponse: ({ data }) => { diff --git a/src/components/Facility/TreatmentSummary.tsx b/src/components/Facility/TreatmentSummary.tsx index 904534123c5..b3c91d801eb 100644 --- a/src/components/Facility/TreatmentSummary.tsx +++ b/src/components/Facility/TreatmentSummary.tsx @@ -16,7 +16,7 @@ import { PatientModel } from "@/components/Patient/models"; import { GENDER_TYPES } from "@/common/constants"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { formatDate, formatDateTime, formatPatientAge } from "@/Utils/utils"; export interface ITreatmentSummaryProps { @@ -32,15 +32,18 @@ export default function TreatmentSummary({ const { t } = useTranslation(); const date = new Date(); - const { data: patientData } = useQuery(routes.getPatient, { + const { data: patientData } = useTanStackQueryInstead(routes.getPatient, { pathParams: { id: patientId }, prefetch: patientId !== undefined, }); - const { data: consultationData } = useQuery(routes.getConsultation, { - pathParams: { id: consultationId }, - prefetch: consultationId !== undefined, - }); + const { data: consultationData } = useTanStackQueryInstead( + routes.getConsultation, + { + pathParams: { id: consultationId }, + prefetch: consultationId !== undefined, + }, + ); return (
@@ -286,10 +289,13 @@ interface IInvestigationsSection { function InvestigationsSection({ consultationId }: IInvestigationsSection) { const { t } = useTranslation(); - const { data: investigations } = useQuery(routes.getInvestigation, { - pathParams: { consultation_external_id: consultationId }, - prefetch: consultationId !== undefined, - }); + const { data: investigations } = useTanStackQueryInstead( + routes.getInvestigation, + { + pathParams: { consultation_external_id: consultationId }, + prefetch: consultationId !== undefined, + }, + ); return investigations?.results.length ? (
@@ -426,10 +432,13 @@ interface IPrescriptionsSection { function PrescriptionsSection({ consultationId }: IPrescriptionsSection) { const { t } = useTranslation(); - const { data: prescriptions } = useQuery(MedicineRoutes.listPrescriptions, { - pathParams: { consultation: consultationId }, - query: { discontinued: false }, - }); + const { data: prescriptions } = useTanStackQueryInstead( + MedicineRoutes.listPrescriptions, + { + pathParams: { consultation: consultationId }, + query: { discontinued: false }, + }, + ); return prescriptions?.results.length ? (
diff --git a/src/components/Facility/TriageForm.tsx b/src/components/Facility/TriageForm.tsx index 472b779170a..607adb0172f 100644 --- a/src/components/Facility/TriageForm.tsx +++ b/src/components/Facility/TriageForm.tsx @@ -19,7 +19,7 @@ import useAppHistory from "@/hooks/useAppHistory"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { dateQueryString, scrollTo } from "@/Utils/utils"; interface Props extends PatientStatsModel { @@ -70,7 +70,7 @@ export const TriageForm = ({ facilityId, id }: Props) => { const headerText = !id ? "Add Triage" : "Edit Triage"; const buttonText = !id ? "Save Triage" : "Update Triage"; - const triageDetailsQuery = useQuery(routes.getTriageDetails, { + const triageDetailsQuery = useTanStackQueryInstead(routes.getTriageDetails, { pathParams: { facilityId, id: id! }, prefetch: !!id, onResponse: ({ data }) => { @@ -85,13 +85,13 @@ export const TriageForm = ({ facilityId, id }: Props) => { }, }); - const patientStatsQuery = useQuery(routes.getTriage, { + const patientStatsQuery = useTanStackQueryInstead(routes.getTriage, { pathParams: { facilityId }, }); const patientStatsData = patientStatsQuery.data?.results ?? []; - const facilityQuery = useQuery(routes.getAnyFacility, { + const facilityQuery = useTanStackQueryInstead(routes.getAnyFacility, { pathParams: { id: facilityId }, }); const facilityName = facilityQuery.data?.name ?? ""; diff --git a/src/components/Files/FileBlock.tsx b/src/components/Files/FileBlock.tsx index 794cdedd1d3..5015a67e2e1 100644 --- a/src/components/Files/FileBlock.tsx +++ b/src/components/Files/FileBlock.tsx @@ -11,7 +11,7 @@ import { FileManagerResult } from "@/hooks/useFileManager"; import { FILE_EXTENSIONS } from "@/common/constants"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; export interface FileBlockProps { file: FileUploadModel; @@ -32,7 +32,7 @@ export default function FileBlock(props: FileBlockProps) { const filetype = fileManager.getFileType(file); - const fileData = useQuery(routes.retrieveUpload, { + const fileData = useTanStackQueryInstead(routes.retrieveUpload, { query: { file_type: fileManager.type, associating_id }, pathParams: { id: file.id || "" }, prefetch: filetype === "AUDIO" && !file.is_archived, diff --git a/src/components/Files/FileUpload.tsx b/src/components/Files/FileUpload.tsx index 50ab3ffdb01..6ae072b857a 100644 --- a/src/components/Files/FileUpload.tsx +++ b/src/components/Files/FileUpload.tsx @@ -19,7 +19,7 @@ import { RESULTS_PER_PAGE_LIMIT } from "@/common/constants"; import { NonReadOnlyUsers } from "@/Utils/AuthorizeFor"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; export const LinearProgressWithLabel = (props: { value: number }) => { return ( @@ -118,7 +118,7 @@ export const FileUpload = (props: FileUploadProps) => { CLAIM: claimId, }[type] || ""; - const activeFilesQuery = useQuery(routes.viewUpload, { + const activeFilesQuery = useTanStackQueryInstead(routes.viewUpload, { query: { file_type: type, associating_id: associatedId, @@ -128,7 +128,7 @@ export const FileUpload = (props: FileUploadProps) => { }, }); - const archivedFilesQuery = useQuery(routes.viewUpload, { + const archivedFilesQuery = useTanStackQueryInstead(routes.viewUpload, { query: { file_type: type, associating_id: associatedId, @@ -138,7 +138,7 @@ export const FileUpload = (props: FileUploadProps) => { }, }); - const dischargeSummaryQuery = useQuery(routes.viewUpload, { + const dischargeSummaryQuery = useTanStackQueryInstead(routes.viewUpload, { query: { file_type: "DISCHARGE_SUMMARY", associating_id: associatedId, diff --git a/src/components/HCX/InsurerAutocomplete.tsx b/src/components/HCX/InsurerAutocomplete.tsx index 4c450fcd34e..45c3f61e691 100644 --- a/src/components/HCX/InsurerAutocomplete.tsx +++ b/src/components/HCX/InsurerAutocomplete.tsx @@ -8,7 +8,7 @@ import { } from "@/components/Form/FormFields/Utils"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { mergeQueryOptions } from "@/Utils/utils"; export type InsurerOptionModel = { @@ -25,9 +25,12 @@ export default function InsurerAutocomplete(props: Props) { const [query, setQuery] = useState(""); - const { data, loading } = useQuery(routes.hcx.policies.listPayors, { - query: { query, limit: 10 }, - }); + const { data, loading } = useTanStackQueryInstead( + routes.hcx.policies.listPayors, + { + query: { query, limit: 10 }, + }, + ); return ( diff --git a/src/components/HCX/PatientInsuranceDetailsEditor.tsx b/src/components/HCX/PatientInsuranceDetailsEditor.tsx index 9d960411b18..1fcaea13ad9 100644 --- a/src/components/HCX/PatientInsuranceDetailsEditor.tsx +++ b/src/components/HCX/PatientInsuranceDetailsEditor.tsx @@ -10,7 +10,7 @@ import HCXPolicyValidator from "@/components/HCX/validators"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; interface Props { patient: string; @@ -31,7 +31,7 @@ export default function PatientInsuranceDetailsEditor({ const [insuranceDetailsError, setInsuranceDetailsError] = useState(); const [isUpdating, setIsUpdating] = useState(false); - useQuery(routes.hcx.policies.list, { + useTanStackQueryInstead(routes.hcx.policies.list, { query: { patient }, onResponse(res) { if (res?.res?.ok && res.data) { diff --git a/src/components/HCX/PolicyEligibilityCheck.tsx b/src/components/HCX/PolicyEligibilityCheck.tsx index 4515819fc26..53d08a4aaf8 100644 --- a/src/components/HCX/PolicyEligibilityCheck.tsx +++ b/src/components/HCX/PolicyEligibilityCheck.tsx @@ -12,7 +12,7 @@ import { useMessageListener } from "@/hooks/useMessageListener"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; interface Props { className?: string; @@ -34,7 +34,9 @@ export default function HCXPolicyEligibilityCheck({ refetch, data: policiesResponse, loading, - } = useQuery(routes.hcx.policies.list, { query: { patient } }); + } = useTanStackQueryInstead(routes.hcx.policies.list, { + query: { patient }, + }); useMessageListener((data) => { if ( diff --git a/src/components/LogUpdate/CriticalCareEditor.tsx b/src/components/LogUpdate/CriticalCareEditor.tsx index c6b48f24909..11978b06be8 100644 --- a/src/components/LogUpdate/CriticalCareEditor.tsx +++ b/src/components/LogUpdate/CriticalCareEditor.tsx @@ -17,7 +17,7 @@ import { useSlugs } from "@/hooks/useSlug"; import { Success } from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { classNames } from "@/Utils/utils"; type Props = { @@ -32,7 +32,7 @@ type SectionKey = keyof typeof LogUpdateSections; export default function CriticalCareEditor(props: Props) { const { t } = useTranslation(); - const query = useQuery(routes.getDailyReport, { + const query = useTanStackQueryInstead(routes.getDailyReport, { pathParams: { consultationId: props.consultationId, id: props.id }, }); diff --git a/src/components/LogUpdate/CriticalCarePreview.tsx b/src/components/LogUpdate/CriticalCarePreview.tsx index e9f4c697d82..0ec8204868c 100644 --- a/src/components/LogUpdate/CriticalCarePreview.tsx +++ b/src/components/LogUpdate/CriticalCarePreview.tsx @@ -17,7 +17,7 @@ import PainChart from "@/components/LogUpdate/components/PainChart"; import { DailyRoundsModel } from "@/components/Patient/models"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { ValueDescription, classNames, @@ -34,7 +34,7 @@ type Props = { export default function CriticalCarePreview(props: Props) { const { t } = useTranslation(); - const { data } = useQuery(routes.getDailyReport, { + const { data } = useTanStackQueryInstead(routes.getDailyReport, { pathParams: { consultationId: props.consultationId, id: props.id, diff --git a/src/components/LogUpdate/Sections/RespiratorySupport/index.tsx b/src/components/LogUpdate/Sections/RespiratorySupport/index.tsx index d8641dd135a..fb12b8a1667 100644 --- a/src/components/LogUpdate/Sections/RespiratorySupport/index.tsx +++ b/src/components/LogUpdate/Sections/RespiratorySupport/index.tsx @@ -19,13 +19,13 @@ import { RESPIRATORY_SUPPORT } from "@/common/constants"; import { Warn } from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { rangeValueDescription } from "@/Utils/utils"; const RespiratorySupport = ({ log, onChange }: LogUpdateSectionProps) => { const { t } = useTranslation(); const [facilityId, consultationId] = useSlugs("facility", "consultation"); - const consultationQuery = useQuery(routes.getConsultation, { + const consultationQuery = useTanStackQueryInstead(routes.getConsultation, { pathParams: { id: consultationId }, }); diff --git a/src/components/Medicine/CreatePrescriptionForm.tsx b/src/components/Medicine/CreatePrescriptionForm.tsx index c80e96094ae..ea2a661ae1c 100644 --- a/src/components/Medicine/CreatePrescriptionForm.tsx +++ b/src/components/Medicine/CreatePrescriptionForm.tsx @@ -19,7 +19,7 @@ import { PrescriptionFormValidator } from "@/components/Medicine/validators"; import useSlug from "@/hooks/useSlug"; import { Success } from "@/Utils/Notifications"; -import useMutation from "@/Utils/request/useMutation"; +import useDeprecatedMutation from "@/Utils/request/useMutation"; export default function CreatePrescriptionForm(props: { prescription: Prescription; @@ -27,7 +27,7 @@ export default function CreatePrescriptionForm(props: { }) { const { t } = useTranslation(); const consultation = useSlug("consultation"); - const mutation = useMutation(MedicineRoutes.createPrescription, { + const mutation = useDeprecatedMutation(MedicineRoutes.createPrescription, { pathParams: { consultation }, }); diff --git a/src/components/Medicine/MedibaseAutocompleteFormField.tsx b/src/components/Medicine/MedibaseAutocompleteFormField.tsx index daca53f08ff..d2d57b1db85 100644 --- a/src/components/Medicine/MedibaseAutocompleteFormField.tsx +++ b/src/components/Medicine/MedibaseAutocompleteFormField.tsx @@ -11,7 +11,7 @@ import { import { MedibaseMedicine } from "@/components/Medicine/models"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { mergeQueryOptions } from "@/Utils/utils"; export default function MedibaseAutocompleteFormField( @@ -22,9 +22,12 @@ export default function MedibaseAutocompleteFormField( const [query, setQuery] = useState(""); const [type, setType] = useState(); - const { data, loading } = useQuery(routes.listMedibaseMedicines, { - query: { query, type }, - }); + const { data, loading } = useTanStackQueryInstead( + routes.listMedibaseMedicines, + { + query: { query, type }, + }, + ); return ( { limit: 100, }; - const { data, loading, refetch } = useQuery( + const { data, loading, refetch } = useTanStackQueryInstead( MedicineRoutes.listPrescriptions, { pathParams: { consultation }, @@ -46,15 +46,18 @@ const MedicineAdministrationSheet = ({ readonly, is_prn }: Props) => { }, ); - const discontinuedPrescriptions = useQuery(MedicineRoutes.listPrescriptions, { - pathParams: { consultation }, - query: { - ...filters, - limit: 100, - discontinued: true, + const discontinuedPrescriptions = useTanStackQueryInstead( + MedicineRoutes.listPrescriptions, + { + pathParams: { consultation }, + query: { + ...filters, + limit: 100, + discontinued: true, + }, + prefetch: !showDiscontinued, }, - prefetch: !showDiscontinued, - }); + ); const discontinuedCount = discontinuedPrescriptions.data?.count; diff --git a/src/components/Medicine/MedicinePrescriptionSummary.tsx b/src/components/Medicine/MedicinePrescriptionSummary.tsx index 13481a4f1ff..572e7b915fb 100644 --- a/src/components/Medicine/MedicinePrescriptionSummary.tsx +++ b/src/components/Medicine/MedicinePrescriptionSummary.tsx @@ -8,7 +8,7 @@ import Loading from "@/components/Common/Loading"; import { MedibaseMedicine, Prescription } from "@/components/Medicine/models"; import MedicineRoutes from "@/components/Medicine/routes"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { humanizeStrings } from "@/Utils/utils"; interface MedicinePrescriptionSummaryProps { @@ -24,7 +24,7 @@ export const MedicinePrescriptionSummary = ({ name: "", medicineId: "", }); - const { data } = useQuery(MedicineRoutes.listPrescriptions, { + const { data } = useTanStackQueryInstead(MedicineRoutes.listPrescriptions, { pathParams: { consultation }, query: { limit: 100 }, }); @@ -120,12 +120,15 @@ export default function ConsultationMedicineLogs({ consultationId, medicineId, }: ConsultationMedicineLogsProps) { - const { data, loading } = useQuery(MedicineRoutes.listPrescriptions, { - pathParams: { consultation: consultationId }, - query: { - medicine: medicineId, + const { data, loading } = useTanStackQueryInstead( + MedicineRoutes.listPrescriptions, + { + pathParams: { consultation: consultationId }, + query: { + medicine: medicineId, + }, }, - }); + ); if (loading) { return ; diff --git a/src/components/Medicine/PrescriptionBuilder.tsx b/src/components/Medicine/PrescriptionBuilder.tsx index 9de905d3071..50aca2610f8 100644 --- a/src/components/Medicine/PrescriptionBuilder.tsx +++ b/src/components/Medicine/PrescriptionBuilder.tsx @@ -19,7 +19,7 @@ import MedicineRoutes from "@/components/Medicine/routes"; import useSlug from "@/hooks/useSlug"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { compareBy } from "@/Utils/utils"; interface Props { @@ -43,15 +43,18 @@ export default function PrescriptionBuilder({ const [showDiscontinueFor, setShowDiscontinueFor] = useState(); const [showAdministerFor, setShowAdministerFor] = useState(); - const { data, refetch } = useQuery(MedicineRoutes.listPrescriptions, { - pathParams: { consultation }, - query: { - dosage_type: is_prn ? "PRN" : "REGULAR,TITRATED", - prescription_type, - discontinued, - limit: 100, + const { data, refetch } = useTanStackQueryInstead( + MedicineRoutes.listPrescriptions, + { + pathParams: { consultation }, + query: { + dosage_type: is_prn ? "PRN" : "REGULAR,TITRATED", + prescription_type, + discontinued, + limit: 100, + }, }, - }); + ); return (
diff --git a/src/components/Medicine/PrescriptionsTable.tsx b/src/components/Medicine/PrescriptionsTable.tsx index 72393199e32..04a7735e3b7 100644 --- a/src/components/Medicine/PrescriptionsTable.tsx +++ b/src/components/Medicine/PrescriptionsTable.tsx @@ -13,7 +13,7 @@ import MedicineRoutes from "@/components/Medicine/routes"; import useSlug from "@/hooks/useSlug"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { formatDateTime } from "@/Utils/utils"; interface Props { @@ -29,7 +29,7 @@ export default function PrescriptionsTable({ const { t } = useTranslation(); const [detailedViewFor, setDetailedViewFor] = useState(); - const { data } = useQuery(MedicineRoutes.listPrescriptions, { + const { data } = useTanStackQueryInstead(MedicineRoutes.listPrescriptions, { pathParams: { consultation }, query: { dosage_type: is_prn ? "PRN" : "REGULAR,TITRATED", diff --git a/src/components/Medicine/PrescrpitionTimeline.tsx b/src/components/Medicine/PrescrpitionTimeline.tsx index 29b72775eb9..16ac603c54b 100644 --- a/src/components/Medicine/PrescrpitionTimeline.tsx +++ b/src/components/Medicine/PrescrpitionTimeline.tsx @@ -21,7 +21,7 @@ import useSlug from "@/hooks/useSlug"; import dayjs from "@/Utils/dayjs"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { classNames, formatDateTime, formatTime } from "@/Utils/utils"; interface MedicineAdministeredEvent extends TimelineEvent<"administered"> { @@ -47,7 +47,7 @@ export default function PrescrpitionTimeline({ readonly, }: Props) { const consultation = useSlug("consultation"); - const { data, refetch, loading } = useQuery( + const { data, refetch, loading } = useTanStackQueryInstead( MedicineRoutes.listAdministrations, { pathParams: { consultation }, diff --git a/src/components/Medicine/PrintPreview.tsx b/src/components/Medicine/PrintPreview.tsx index a5af06e7735..5c9ef47f3fc 100644 --- a/src/components/Medicine/PrintPreview.tsx +++ b/src/components/Medicine/PrintPreview.tsx @@ -10,7 +10,7 @@ import MedicineRoutes from "@/components/Medicine/routes"; import { useSlugs } from "@/hooks/useSlug"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { classNames, formatDate, @@ -23,18 +23,21 @@ export default function PrescriptionsPrintPreview() { const { t } = useTranslation(); const [patientId, consultationId] = useSlugs("patient", "consultation"); - const patientQuery = useQuery(routes.getPatient, { + const patientQuery = useTanStackQueryInstead(routes.getPatient, { pathParams: { id: patientId }, }); - const encounterQuery = useQuery(routes.getConsultation, { + const encounterQuery = useTanStackQueryInstead(routes.getConsultation, { pathParams: { id: consultationId }, }); - const prescriptionsQuery = useQuery(MedicineRoutes.listPrescriptions, { - pathParams: { consultation: consultationId }, - query: { discontinued: false, limit: 100 }, - }); + const prescriptionsQuery = useTanStackQueryInstead( + MedicineRoutes.listPrescriptions, + { + pathParams: { consultation: consultationId }, + query: { discontinued: false, limit: 100 }, + }, + ); const patient = patientQuery.data; const encounter = encounterQuery.data; diff --git a/src/components/Notifications/NoticeBoard.tsx b/src/components/Notifications/NoticeBoard.tsx index e1f00075000..452cd7f568e 100644 --- a/src/components/Notifications/NoticeBoard.tsx +++ b/src/components/Notifications/NoticeBoard.tsx @@ -6,12 +6,12 @@ import Loading from "@/components/Common/Loading"; import Page from "@/components/Common/Page"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { formatDateTime, formatName } from "@/Utils/utils"; export const NoticeBoard = () => { const { t } = useTranslation(); - const { data, loading } = useQuery(routes.getNotifications, { + const { data, loading } = useTanStackQueryInstead(routes.getNotifications, { query: { offset: 0, event: "MESSAGE", medium_sent: "SYSTEM" }, }); diff --git a/src/components/Notifications/ShowPushNotification.tsx b/src/components/Notifications/ShowPushNotification.tsx index b1bc7c34397..0b79624a550 100644 --- a/src/components/Notifications/ShowPushNotification.tsx +++ b/src/components/Notifications/ShowPushNotification.tsx @@ -1,10 +1,10 @@ import { NotificationData } from "@/components/Notifications/models"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; export default function ShowPushNotification({ id }: { id: string }) { - useQuery(routes.getNotificationData, { + useTanStackQueryInstead(routes.getNotificationData, { pathParams: { id }, onResponse(res) { if (res.data) { diff --git a/src/components/Patient/DailyRoundListDetails.tsx b/src/components/Patient/DailyRoundListDetails.tsx index 2a2b76d26b2..66ca76c9a44 100644 --- a/src/components/Patient/DailyRoundListDetails.tsx +++ b/src/components/Patient/DailyRoundListDetails.tsx @@ -11,7 +11,7 @@ import Page from "@/components/Common/Page"; import { DailyRoundsModel } from "@/components/Patient/models"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { formatDateTime } from "@/Utils/utils"; export const DailyRoundListDetails = (props: any) => { @@ -20,14 +20,17 @@ export const DailyRoundListDetails = (props: any) => { const [dailyRoundListDetailsData, setDailyRoundListDetails] = useState({}); - const { loading: isLoading } = useQuery(routes.getDailyReport, { - pathParams: { consultationId, id }, - onResponse: ({ data }) => { - if (data) { - setDailyRoundListDetails(data); - } + const { loading: isLoading } = useTanStackQueryInstead( + routes.getDailyReport, + { + pathParams: { consultationId, id }, + onResponse: ({ data }) => { + if (data) { + setDailyRoundListDetails(data); + } + }, }, - }); + ); if (isLoading) { return ; diff --git a/src/components/Patient/DiagnosesFilter.tsx b/src/components/Patient/DiagnosesFilter.tsx index 912a10cfde2..0258e96c5ba 100644 --- a/src/components/Patient/DiagnosesFilter.tsx +++ b/src/components/Patient/DiagnosesFilter.tsx @@ -9,7 +9,7 @@ import useDebounce from "@/hooks/useDebounce"; import { Error } from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { mergeQueryOptions } from "@/Utils/utils"; export const FILTER_BY_DIAGNOSES_KEYS = [ @@ -39,10 +39,13 @@ interface Props { export default function DiagnosesFilter(props: Props) { const { t } = useTranslation(); const [diagnoses, setDiagnoses] = useState([]); - const { res, data, loading, refetch } = useQuery(routes.listICD11Diagnosis, { - silent: true, - prefetch: false, - }); + const { res, data, loading, refetch } = useTanStackQueryInstead( + routes.listICD11Diagnosis, + { + silent: true, + prefetch: false, + }, + ); const handleQuery = useDebounce( (query: string) => refetch({ query: { query } }), diff --git a/src/components/Patient/FileUploadPage.tsx b/src/components/Patient/FileUploadPage.tsx index d38b149ebeb..77f83788af2 100644 --- a/src/components/Patient/FileUploadPage.tsx +++ b/src/components/Patient/FileUploadPage.tsx @@ -2,7 +2,7 @@ import Page from "@/components/Common/Page"; import { FileUpload } from "@/components/Files/FileUpload"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; export default function FileUploadPage(props: { facilityId: string; @@ -11,7 +11,7 @@ export default function FileUploadPage(props: { type: "CONSULTATION" | "PATIENT"; }) { const { facilityId, patientId, consultationId, type } = props; - const { data: patient } = useQuery(routes.getPatient, { + const { data: patient } = useTanStackQueryInstead(routes.getPatient, { pathParams: { id: patientId }, prefetch: !!patientId, }); diff --git a/src/components/Patient/InsuranceDetails.tsx b/src/components/Patient/InsuranceDetails.tsx index 3efe7866316..1796a657b9e 100644 --- a/src/components/Patient/InsuranceDetails.tsx +++ b/src/components/Patient/InsuranceDetails.tsx @@ -4,7 +4,7 @@ import { HCXPolicyModel } from "@/components/HCX/models"; import { InsuranceDetailsCard } from "@/components/Patient/InsuranceDetailsCard"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; interface IProps { facilityId: string; @@ -14,7 +14,7 @@ interface IProps { export const InsuranceDetails = (props: IProps) => { const { facilityId, id } = props; - const { data: insuranceDetials, loading } = useQuery( + const { data: insuranceDetials, loading } = useTanStackQueryInstead( routes.hcx.policies.list, { query: { diff --git a/src/components/Patient/ManagePatients.tsx b/src/components/Patient/ManagePatients.tsx index 25a1f9166ed..0cae44163b2 100644 --- a/src/components/Patient/ManagePatients.tsx +++ b/src/components/Patient/ManagePatients.tsx @@ -38,7 +38,7 @@ import { AdvancedFilterButton } from "../../CAREUI/interactive/FiltersSlideover" import { triggerGoal } from "../../Integrations/Plausible"; import * as Notification from "../../Utils/Notifications"; import request from "../../Utils/request/request"; -import useQuery from "../../Utils/request/useQuery"; +import useTanStackQueryInstead from "../../Utils/request/useQuery"; import { formatPatientAge, humanizeStrings, @@ -289,9 +289,12 @@ export const PatientManager = () => { return cleanedData; }; - const { loading: isLoading, data } = useQuery(routes.patientList, { - query: params, - }); + const { loading: isLoading, data } = useTanStackQueryInstead( + routes.patientList, + { + query: params, + }, + ); const getTheCategoryFromId = () => { let category_name; @@ -306,27 +309,30 @@ export const PatientManager = () => { } }; - const { data: districtData } = useQuery(routes.getDistrict, { + const { data: districtData } = useTanStackQueryInstead(routes.getDistrict, { pathParams: { id: qParams.district, }, prefetch: !!Number(qParams.district), }); - const { data: LocalBodyData } = useQuery(routes.getLocalBody, { + const { data: LocalBodyData } = useTanStackQueryInstead(routes.getLocalBody, { pathParams: { id: qParams.lsgBody, }, prefetch: !!Number(qParams.lsgBody), }); - const { data: facilityData } = useQuery(routes.getAnyFacility, { - pathParams: { - id: qParams.facility, + const { data: facilityData } = useTanStackQueryInstead( + routes.getAnyFacility, + { + pathParams: { + id: qParams.facility, + }, + prefetch: !!qParams.facility, }, - prefetch: !!qParams.facility, - }); - const { data: facilityAssetLocationData } = useQuery( + ); + const { data: facilityAssetLocationData } = useTanStackQueryInstead( routes.getFacilityAssetLocation, { pathParams: { @@ -336,19 +342,8 @@ export const PatientManager = () => { prefetch: !!qParams.last_consultation_current_bed__location, }, ); - /* - const { data: patientsWithNoConsentsData } = useQuery(routes.patientList, { - query: { - ...qParams, - limit: 1, - last_consultation__consent_types: "None", - is_active: "True", - }, - }); - const patientsWithNoConsents = patientsWithNoConsentsData?.count; - */ - const { data: permittedFacilities } = useQuery( + const { data: permittedFacilities } = useTanStackQueryInstead( routes.getPermittedFacilities, { query: { limit: 1 }, diff --git a/src/components/Patient/PatientConsentRecords.tsx b/src/components/Patient/PatientConsentRecords.tsx index cbeb56b894f..c2232c91c09 100644 --- a/src/components/Patient/PatientConsentRecords.tsx +++ b/src/components/Patient/PatientConsentRecords.tsx @@ -22,7 +22,7 @@ import { import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { formatDateTime } from "@/Utils/utils"; export default function PatientConsentRecords(props: { @@ -56,21 +56,24 @@ export default function PatientConsentRecords(props: { }, }); - const { data: patient } = useQuery(routes.getPatient, { + const { data: patient } = useTanStackQueryInstead(routes.getPatient, { pathParams: { id: patientId, }, }); - const { data: consentRecordsData, refetch } = useQuery(routes.listConsents, { - pathParams: { - consultationId, - }, - query: { - limit: 1000, - offset: 0, + const { data: consentRecordsData, refetch } = useTanStackQueryInstead( + routes.listConsents, + { + pathParams: { + consultationId, + }, + query: { + limit: 1000, + offset: 0, + }, }, - }); + ); const consentRecords = consentRecordsData?.results; diff --git a/src/components/Patient/PatientDetailsTab/Demography.tsx b/src/components/Patient/PatientDetailsTab/Demography.tsx index b9d2b8fece4..e5bed5abfee 100644 --- a/src/components/Patient/PatientDetailsTab/Demography.tsx +++ b/src/components/Patient/PatientDetailsTab/Demography.tsx @@ -15,7 +15,7 @@ import { GENDER_TYPES } from "@/common/constants"; import { NonReadOnlyUsers } from "@/Utils/AuthorizeFor"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { formatName, formatPatientAge } from "@/Utils/utils"; import { PatientProps } from "."; @@ -61,11 +61,14 @@ export const Demography = (props: PatientProps) => { }; }, [patientData.assigned_to_object]); - const { data: insuranceDetials } = useQuery(routes.hcx.policies.list, { - query: { - patient: id, + const { data: insuranceDetials } = useTanStackQueryInstead( + routes.hcx.policies.list, + { + query: { + patient: id, + }, }, - }); + ); const patientGender = GENDER_TYPES.find( (i) => i.id === patientData.gender, diff --git a/src/components/Patient/PatientDetailsTab/EncounterHistory.tsx b/src/components/Patient/PatientDetailsTab/EncounterHistory.tsx index 71865483800..b81009efa74 100644 --- a/src/components/Patient/PatientDetailsTab/EncounterHistory.tsx +++ b/src/components/Patient/PatientDetailsTab/EncounterHistory.tsx @@ -12,7 +12,7 @@ import useAuthUser from "@/hooks/useAuthUser"; import { triggerGoal } from "@/Integrations/Plausible"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { PatientProps } from "."; import { PatientModel } from "../models"; @@ -29,20 +29,23 @@ const EncounterHistory = (props: PatientProps) => { const { t } = useTranslation(); - const { loading: isLoading, refetch } = useQuery(routes.getPatient, { - pathParams: { - id, + const { loading: isLoading, refetch } = useTanStackQueryInstead( + routes.getPatient, + { + pathParams: { + id, + }, + onResponse: ({ res, data }) => { + if (res?.ok && data) { + setPatientData(data); + } + triggerGoal("Patient Profile Viewed", { + facilityId: facilityId, + userId: authUser.id, + }); + }, }, - onResponse: ({ res, data }) => { - if (res?.ok && data) { - setPatientData(data); - } - triggerGoal("Patient Profile Viewed", { - facilityId: facilityId, - userId: authUser.id, - }); - }, - }); + ); if (isLoading) { return ; diff --git a/src/components/Patient/PatientDetailsTab/ShiftingHistory.tsx b/src/components/Patient/PatientDetailsTab/ShiftingHistory.tsx index b7ef154bf4d..b9f63da5512 100644 --- a/src/components/Patient/PatientDetailsTab/ShiftingHistory.tsx +++ b/src/components/Patient/PatientDetailsTab/ShiftingHistory.tsx @@ -11,7 +11,7 @@ import useFilters from "@/hooks/useFilters"; import { NonReadOnlyUsers } from "@/Utils/AuthorizeFor"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { PatientProps } from "."; import { PatientModel } from "../models"; @@ -30,16 +30,19 @@ const ShiftingHistory = (props: PatientProps) => { ); }; - const { data: shiftData, loading } = useQuery(routes.listShiftRequests, { - query: { - ...formatFilter({ - ...qParams, - offset: (qParams.page ? qParams.page - 1 : 0) * resultsPerPage, - }), - patient: id, + const { data: shiftData, loading } = useTanStackQueryInstead( + routes.listShiftRequests, + { + query: { + ...formatFilter({ + ...qParams, + offset: (qParams.page ? qParams.page - 1 : 0) * resultsPerPage, + }), + patient: id, + }, + prefetch: !!id, }, - prefetch: !!id, - }); + ); return (
diff --git a/src/components/Patient/PatientFilter.tsx b/src/components/Patient/PatientFilter.tsx index 4d0e49e9e62..e2ab6cd30b4 100644 --- a/src/components/Patient/PatientFilter.tsx +++ b/src/components/Patient/PatientFilter.tsx @@ -40,7 +40,7 @@ import { import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { dateQueryString } from "@/Utils/utils"; const getDate = (value: any) => @@ -108,19 +108,19 @@ export default function PatientFilter(props: any) { review_missed: filter.review_missed || null, }); - useQuery(routes.getAnyFacility, { + useTanStackQueryInstead(routes.getAnyFacility, { pathParams: { id: filter.facility }, prefetch: !!filter.facility, onResponse: ({ data }) => setFilterState({ facility_ref: data }), }); - useQuery(routes.getDistrict, { + useTanStackQueryInstead(routes.getDistrict, { pathParams: { id: filter.district }, prefetch: !!filter.district, onResponse: ({ data }) => setFilterState({ district_ref: data }), }); - useQuery(routes.getLocalBody, { + useTanStackQueryInstead(routes.getLocalBody, { pathParams: { id: filter.lsgBody }, prefetch: !!filter.lsgBody, onResponse: ({ data }) => setFilterState({ lsgBody_ref: data }), diff --git a/src/components/Patient/PatientHome.tsx b/src/components/Patient/PatientHome.tsx index b69ae75751e..48d754d6d26 100644 --- a/src/components/Patient/PatientHome.tsx +++ b/src/components/Patient/PatientHome.tsx @@ -23,7 +23,7 @@ import { triggerGoal } from "../../Integrations/Plausible"; import { NonReadOnlyUsers } from "../../Utils/AuthorizeFor"; import * as Notification from "../../Utils/Notifications"; import request from "../../Utils/request/request"; -import useQuery from "../../Utils/request/useQuery"; +import useTanStackQueryInstead from "../../Utils/request/useQuery"; import { formatDateTime, formatName, @@ -75,20 +75,23 @@ export const PatientHome = (props: { const initErr: any = {}; const errors = initErr; - const { loading: isLoading, refetch } = useQuery(routes.getPatient, { - pathParams: { - id, - }, - onResponse: ({ res, data }) => { - if (res?.ok && data) { - setPatientData(data); - } - triggerGoal("Patient Profile Viewed", { - facilityId: facilityId, - userId: authUser.id, - }); + const { loading: isLoading, refetch } = useTanStackQueryInstead( + routes.getPatient, + { + pathParams: { + id, + }, + onResponse: ({ res, data }) => { + if (res?.ok && data) { + setPatientData(data); + } + triggerGoal("Patient Profile Viewed", { + facilityId: facilityId, + userId: authUser.id, + }); + }, }, - }); + ); const handleAssignedVolunteer = async () => { const previousVolunteerId = patientData?.assigned_to; @@ -128,7 +131,7 @@ export const PatientHome = (props: { }; const consultation = patientData?.last_consultation; - const skillsQuery = useQuery(routes.userListSkill, { + const skillsQuery = useTanStackQueryInstead(routes.userListSkill, { pathParams: { username: consultation?.treating_physician_object?.username ?? "", }, diff --git a/src/components/Patient/PatientInfoCard.tsx b/src/components/Patient/PatientInfoCard.tsx index 486e8b103fd..ad2c5314d22 100644 --- a/src/components/Patient/PatientInfoCard.tsx +++ b/src/components/Patient/PatientInfoCard.tsx @@ -36,7 +36,7 @@ import * as Notification from "@/Utils/Notifications"; import dayjs from "@/Utils/dayjs"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { classNames, formatDate, @@ -123,7 +123,7 @@ export default function PatientInfoCard(props: PatientInfoCardProps) { return false; }; - const skillsQuery = useQuery(routes.userListSkill, { + const skillsQuery = useTanStackQueryInstead(routes.userListSkill, { pathParams: { username: consultation?.treating_physician_object?.username ?? "", }, diff --git a/src/components/Patient/PatientRegister.tsx b/src/components/Patient/PatientRegister.tsx index a7098c24264..eb0594baa82 100644 --- a/src/components/Patient/PatientRegister.tsx +++ b/src/components/Patient/PatientRegister.tsx @@ -1,6 +1,6 @@ import careConfig from "@careConfig"; import { navigate } from "raviger"; -import { useCallback, useEffect, useReducer, useRef, useState } from "react"; +import { useCallback, useEffect, useReducer, useState } from "react"; import { useTranslation } from "react-i18next"; import CareIcon from "@/CAREUI/icons/CareIcon"; @@ -76,7 +76,7 @@ import * as Notification from "@/Utils/Notifications"; import { usePubSub } from "@/Utils/pubsubContext"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { compareBy, dateQueryString, @@ -188,7 +188,6 @@ export const parseOccupationFromExt = (occupation: Occupation) => { }; export const PatientRegister = (props: PatientRegisterProps) => { - const submitController = useRef(); const authUser = useAuthUser(); const { t } = useTranslation(); const { goBack } = useAppHistory(); @@ -394,7 +393,7 @@ export const PatientRegister = (props: PatientRegisterProps) => { [id], ); - useQuery(routes.hcx.policies.list, { + useTanStackQueryInstead(routes.hcx.policies.list, { query: { patient: id, }, @@ -408,7 +407,7 @@ export const PatientRegister = (props: PatientRegisterProps) => { }, }); - const { data: stateData, loading: isStateLoading } = useQuery( + const { data: stateData, loading: isStateLoading } = useTanStackQueryInstead( routes.statesList, ); @@ -421,10 +420,13 @@ export const PatientRegister = (props: PatientRegisterProps) => { [dispatch, fetchData], ); - const { data: facilityObject } = useQuery(routes.getAnyFacility, { - pathParams: { id: facilityId }, - prefetch: !!facilityId, - }); + const { data: facilityObject } = useTanStackQueryInstead( + routes.getAnyFacility, + { + pathParams: { id: facilityId }, + prefetch: !!facilityId, + }, + ); const validateForm = (form: any) => { const errors: Partial> = {}; @@ -706,11 +708,9 @@ export const PatientRegister = (props: PatientRegisterProps) => { ? await request(routes.updatePatient, { pathParams: { id }, body: data, - controllerRef: submitController, }) : await request(routes.addPatient, { body: { ...data, facility: facilityId }, - controllerRef: submitController, }); if (res?.ok && requestData) { publish("patient:upsert", requestData); diff --git a/src/components/Patient/SampleDetails.tsx b/src/components/Patient/SampleDetails.tsx index 9a779446d54..6cede48bfa5 100644 --- a/src/components/Patient/SampleDetails.tsx +++ b/src/components/Patient/SampleDetails.tsx @@ -14,12 +14,12 @@ import { GENDER_TYPES, TEST_TYPE_CHOICES } from "@/common/constants"; import { DetailRoute } from "@/Routers/types"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { formatDateTime, formatPatientAge } from "@/Utils/utils"; export const SampleDetails = ({ id }: DetailRoute) => { const { t } = useTranslation(); - const { loading: isLoading, data: sampleDetails } = useQuery( + const { loading: isLoading, data: sampleDetails } = useTanStackQueryInstead( routes.getTestSample, { pathParams: { diff --git a/src/components/Patient/SampleFilters.tsx b/src/components/Patient/SampleFilters.tsx index b44f6fa3575..6ac3a4532b7 100644 --- a/src/components/Patient/SampleFilters.tsx +++ b/src/components/Patient/SampleFilters.tsx @@ -16,7 +16,7 @@ import { } from "@/common/constants"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; export default function UserFilter(props: any) { const { filter, onChange, closeFilter, removeFilters } = props; @@ -44,15 +44,18 @@ export default function UserFilter(props: any) { onChange(data); }; - const { loading: isFacilityLoading } = useQuery(routes.getAnyFacility, { - pathParams: { - id: filter.facility, + const { loading: isFacilityLoading } = useTanStackQueryInstead( + routes.getAnyFacility, + { + pathParams: { + id: filter.facility, + }, + prefetch: !!filter.facility, + onResponse: ({ data }) => { + setFilterState({ ...filterState, facility_ref: data }); + }, }, - prefetch: !!filter.facility, - onResponse: ({ data }) => { - setFilterState({ ...filterState, facility_ref: data }); - }, - }); + ); return ( ; let reportData: JSX.Element = <>; - const { loading: isLoading, data: sampleData } = useQuery( + const { loading: isLoading, data: sampleData } = useTanStackQueryInstead( routes.sampleReport, { pathParams: { diff --git a/src/components/Patient/SampleTest.tsx b/src/components/Patient/SampleTest.tsx index 0933d03761e..7025faf407e 100644 --- a/src/components/Patient/SampleTest.tsx +++ b/src/components/Patient/SampleTest.tsx @@ -20,7 +20,7 @@ import { ICMR_CATEGORY, SAMPLE_TYPE_CHOICES } from "@/common/constants"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; const initForm: SampleTestModel = { isFastTrack: false, @@ -78,7 +78,7 @@ export const SampleTest = ({ facilityId, patientId }: any) => { const headerText = "Request Sample"; const buttonText = "Confirm your request to send sample for testing"; - const { data } = useQuery(routes.getPatient, { + const { data } = useTanStackQueryInstead(routes.getPatient, { pathParams: { id: patientId, }, diff --git a/src/components/Patient/SampleViewAdmin.tsx b/src/components/Patient/SampleViewAdmin.tsx index ff269c90358..cf86b582dd8 100644 --- a/src/components/Patient/SampleViewAdmin.tsx +++ b/src/components/Patient/SampleViewAdmin.tsx @@ -25,7 +25,7 @@ import { import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { formatDateTime } from "@/Utils/utils"; export default function SampleViewAdmin() { @@ -46,18 +46,21 @@ export default function SampleViewAdmin() { sample: SampleTestModel; }>({ show: false, sample: {} }); - const { data: facilityData } = useQuery(routes.getAnyFacility, { - pathParams: { - id: qParams.facility, + const { data: facilityData } = useTanStackQueryInstead( + routes.getAnyFacility, + { + pathParams: { + id: qParams.facility, + }, + prefetch: !!qParams.facility, }, - prefetch: !!qParams.facility, - }); + ); const { loading: isLoading, data: sampeleData, refetch, - } = useQuery(routes.getTestSampleList, { + } = useTanStackQueryInstead(routes.getTestSampleList, { query: { limit: resultsPerPage, offset: (qParams.page ? qParams.page - 1 : 0) * resultsPerPage, diff --git a/src/components/Patient/ShiftCreate.tsx b/src/components/Patient/ShiftCreate.tsx index 5c11f6cf161..2190cbefac4 100644 --- a/src/components/Patient/ShiftCreate.tsx +++ b/src/components/Patient/ShiftCreate.tsx @@ -32,7 +32,7 @@ import { phonePreg } from "@/common/validation"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { parsePhoneNumber } from "@/Utils/utils"; interface patientShiftProps { @@ -108,7 +108,7 @@ export const ShiftCreate = (props: patientShiftProps) => { errors: { ...initError }, }; - const { data: patientData } = useQuery(routes.getPatient, { + const { data: patientData } = useTanStackQueryInstead(routes.getPatient, { pathParams: { id: patientId, }, diff --git a/src/components/Resource/ResourceBadges.tsx b/src/components/Resource/ResourceBadges.tsx index 36d14d74252..7be946c27a9 100644 --- a/src/components/Resource/ResourceBadges.tsx +++ b/src/components/Resource/ResourceBadges.tsx @@ -1,10 +1,10 @@ import { SHIFTING_FILTER_ORDER } from "@/common/constants"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; export function useFacilityQuery(facilityId: string | undefined) { - return useQuery(routes.getAnyFacility, { + return useTanStackQueryInstead(routes.getAnyFacility, { pathParams: { id: facilityId as string }, prefetch: !!facilityId, }); diff --git a/src/components/Resource/ResourceCreate.tsx b/src/components/Resource/ResourceCreate.tsx index 078b2f84c0c..4786164aa93 100644 --- a/src/components/Resource/ResourceCreate.tsx +++ b/src/components/Resource/ResourceCreate.tsx @@ -29,7 +29,7 @@ import { phonePreg } from "@/common/validation"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { parsePhoneNumber } from "@/Utils/utils"; interface resourceProps { @@ -113,10 +113,13 @@ export default function ResourceCreate(props: resourceProps) { const [state, dispatch] = useReducer(resourceFormReducer, initialState); - const { data: facilityData } = useQuery(routes.getAnyFacility, { - prefetch: facilityId !== undefined, - pathParams: { id: String(facilityId) }, - }); + const { data: facilityData } = useTanStackQueryInstead( + routes.getAnyFacility, + { + prefetch: facilityId !== undefined, + pathParams: { id: String(facilityId) }, + }, + ); const validateForm = () => { const errors = { ...initError }; diff --git a/src/components/Resource/ResourceDetails.tsx b/src/components/Resource/ResourceDetails.tsx index d77bdcc3fea..780118e8e52 100644 --- a/src/components/Resource/ResourceDetails.tsx +++ b/src/components/Resource/ResourceDetails.tsx @@ -9,12 +9,12 @@ import Page from "@/components/Common/Page"; import CommentSection from "@/components/Resource/ResourceCommentSection"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { classNames, formatDateTime, formatName } from "@/Utils/utils"; export default function ResourceDetails(props: { id: string }) { const [isPrintMode, setIsPrintMode] = useState(false); - const { data, loading } = useQuery(routes.getResourceDetails, { + const { data, loading } = useTanStackQueryInstead(routes.getResourceDetails, { pathParams: { id: props.id }, onResponse: ({ res, data }) => { if (!res && !data) { diff --git a/src/components/Resource/ResourceDetailsUpdate.tsx b/src/components/Resource/ResourceDetailsUpdate.tsx index 766cdc5775e..46f92ca27db 100644 --- a/src/components/Resource/ResourceDetailsUpdate.tsx +++ b/src/components/Resource/ResourceDetailsUpdate.tsx @@ -24,7 +24,7 @@ import { RESOURCE_CHOICES } from "@/common/constants"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; interface resourceProps { id: string; @@ -89,13 +89,16 @@ export const ResourceDetailsUpdate = (props: resourceProps) => { const [state, dispatch] = useReducer(resourceFormReducer, initialState); - const { loading: assignedUserLoading } = useQuery(routes.userList, { - onResponse: ({ res, data }) => { - if (res?.ok && data && data.count) { - SetAssignedUser(data.results[0]); - } + const { loading: assignedUserLoading } = useTanStackQueryInstead( + routes.userList, + { + onResponse: ({ res, data }) => { + if (res?.ok && data && data.count) { + SetAssignedUser(data.results[0]); + } + }, }, - }); + ); const validateForm = () => { const errors = { ...initError }; @@ -131,17 +134,20 @@ export const ResourceDetailsUpdate = (props: resourceProps) => { dispatch({ type: "set_form", form }); }; - const { data: resourceDetails } = useQuery(routes.getResourceDetails, { - pathParams: { id: props.id }, - onResponse: ({ res, data }) => { - if (res && data) { - const d = data; - d["status"] = qParams.status || data.status; - dispatch({ type: "set_form", form: d }); - } - setIsLoading(false); + const { data: resourceDetails } = useTanStackQueryInstead( + routes.getResourceDetails, + { + pathParams: { id: props.id }, + onResponse: ({ res, data }) => { + if (res && data) { + const d = data; + d["status"] = qParams.status || data.status; + dispatch({ type: "set_form", form: d }); + } + setIsLoading(false); + }, }, - }); + ); const handleSubmit = async () => { const validForm = validateForm(); diff --git a/src/components/Resource/ResourceFilter.tsx b/src/components/Resource/ResourceFilter.tsx index 10649a0990c..a000c81e1a4 100644 --- a/src/components/Resource/ResourceFilter.tsx +++ b/src/components/Resource/ResourceFilter.tsx @@ -16,7 +16,7 @@ import { RESOURCE_FILTER_ORDER } from "@/common/constants"; import { RESOURCE_CHOICES } from "@/common/constants"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { dateQueryString } from "@/Utils/utils"; const getDate = (value: any) => @@ -40,41 +40,51 @@ export default function ListFilter(props: any) { status: filter.status || null, }); - const { loading: orginFacilityLoading } = useQuery(routes.getAnyFacility, { - prefetch: filter.origin_facility !== undefined, - pathParams: { id: filter.origin_facility }, - onResponse: ({ res, data }) => { - if (res && data) { - setFilterState({ - origin_facility_ref: filter.origin_facility === "" ? "" : data, - }); - } + const { loading: orginFacilityLoading } = useTanStackQueryInstead( + routes.getAnyFacility, + { + prefetch: filter.origin_facility !== undefined, + pathParams: { id: filter.origin_facility }, + onResponse: ({ res, data }) => { + if (res && data) { + setFilterState({ + origin_facility_ref: filter.origin_facility === "" ? "" : data, + }); + } + }, }, - }); + ); - const { loading: resourceFacilityLoading } = useQuery(routes.getAnyFacility, { - prefetch: filter.approving_facility !== undefined, - pathParams: { id: filter.approving_facility }, - onResponse: ({ res, data }) => { - if (res && data) { - setFilterState({ - approving_facility_ref: filter.approving_facility === "" ? "" : data, - }); - } + const { loading: resourceFacilityLoading } = useTanStackQueryInstead( + routes.getAnyFacility, + { + prefetch: filter.approving_facility !== undefined, + pathParams: { id: filter.approving_facility }, + onResponse: ({ res, data }) => { + if (res && data) { + setFilterState({ + approving_facility_ref: + filter.approving_facility === "" ? "" : data, + }); + } + }, }, - }); + ); - const { loading: assignedFacilityLoading } = useQuery(routes.getAnyFacility, { - pathParams: { id: filter.assigned_facility }, - prefetch: filter.assigned_facility !== undefined, - onResponse: ({ res, data }) => { - if (res && data) { - setFilterState({ - assigned_facility_ref: filter.assigned_facility === "" ? "" : data, - }); - } + const { loading: assignedFacilityLoading } = useTanStackQueryInstead( + routes.getAnyFacility, + { + pathParams: { id: filter.assigned_facility }, + prefetch: filter.assigned_facility !== undefined, + onResponse: ({ res, data }) => { + if (res && data) { + setFilterState({ + assigned_facility_ref: filter.assigned_facility === "" ? "" : data, + }); + } + }, }, - }); + ); const setFacility = (selected: any, name: string) => { setFilterState({ diff --git a/src/components/Resource/ResourceList.tsx b/src/components/Resource/ResourceList.tsx index 3bca8377a6b..2b44599f120 100644 --- a/src/components/Resource/ResourceList.tsx +++ b/src/components/Resource/ResourceList.tsx @@ -20,7 +20,7 @@ import useFilters from "@/hooks/useFilters"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { formatDateTime } from "@/Utils/utils"; export default function ListView() { @@ -41,13 +41,16 @@ export default function ListView() { }; const appliedFilters = formatFilter(qParams); - const { loading, data, refetch } = useQuery(routes.listResourceRequests, { - query: formatFilter({ - ...qParams, - limit: resultsPerPage, - offset: (qParams.page ? qParams.page - 1 : 0) * resultsPerPage, - }), - }); + const { loading, data, refetch } = useTanStackQueryInstead( + routes.listResourceRequests, + { + query: formatFilter({ + ...qParams, + limit: resultsPerPage, + offset: (qParams.page ? qParams.page - 1 : 0) * resultsPerPage, + }), + }, + ); const showResourceCardList = (data: ResourceModel[]) => { if (data && !data.length) { diff --git a/src/components/Shifting/ShiftDetails.tsx b/src/components/Shifting/ShiftDetails.tsx index 4a6f6c855bb..58685d20fb1 100644 --- a/src/components/Shifting/ShiftDetails.tsx +++ b/src/components/Shifting/ShiftDetails.tsx @@ -25,7 +25,7 @@ import { } from "@/common/constants"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { formatDateTime, formatName, formatPatientAge } from "@/Utils/utils"; export default function ShiftDetails(props: { id: string }) { @@ -37,7 +37,7 @@ export default function ShiftDetails(props: { id: string }) { ? SHIFTING_CHOICES_WARTIME : SHIFTING_CHOICES_PEACETIME; - const { data, loading } = useQuery(routes.getShiftDetails, { + const { data, loading } = useTanStackQueryInstead(routes.getShiftDetails, { pathParams: { id: props.id }, }); const showCopyToclipBoard = (data: any) => { diff --git a/src/components/Shifting/ShiftDetailsUpdate.tsx b/src/components/Shifting/ShiftDetailsUpdate.tsx index 94eb6d3c6e9..aa2be130ae4 100644 --- a/src/components/Shifting/ShiftDetailsUpdate.tsx +++ b/src/components/Shifting/ShiftDetailsUpdate.tsx @@ -41,7 +41,7 @@ import { import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { parsePhoneNumber } from "@/Utils/utils"; interface patientShiftProps { @@ -152,13 +152,16 @@ export const ShiftDetailsUpdate = (props: patientShiftProps) => { }; } - const { loading: assignedUserLoading } = useQuery(routes.userList, { - query: { id: state.form.assigned_to }, - prefetch: state.form.assigned_to ? true : false, - onResponse: ({ res, data }) => { - if (res?.ok && data?.count) SetAssignedUser(data.results[0]); + const { loading: assignedUserLoading } = useTanStackQueryInstead( + routes.userList, + { + query: { id: state.form.assigned_to }, + prefetch: state.form.assigned_to ? true : false, + onResponse: ({ res, data }) => { + if (res?.ok && data?.count) SetAssignedUser(data.results[0]); + }, }, - }); + ); const validateForm = () => { const errors = { ...initError }; @@ -281,7 +284,7 @@ export const ShiftDetailsUpdate = (props: patientShiftProps) => { } }; - useQuery(routes.getShiftDetails, { + useTanStackQueryInstead(routes.getShiftDetails, { pathParams: { id: props.id }, onResponse: ({ res, data }) => { if (res?.ok && data) { diff --git a/src/components/Shifting/ShiftingBadges.tsx b/src/components/Shifting/ShiftingBadges.tsx index 396935a68c1..cf44099a634 100644 --- a/src/components/Shifting/ShiftingBadges.tsx +++ b/src/components/Shifting/ShiftingBadges.tsx @@ -5,7 +5,7 @@ import { useFacilityQuery } from "@/components/Resource/ResourceBadges"; import { SHIFTING_FILTER_ORDER } from "@/common/constants"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { formatName } from "@/Utils/utils"; export default function BadgesList(props: any) { @@ -18,7 +18,7 @@ export default function BadgesList(props: any) { falseValue: t("no"), }; - const { data: assignedUser } = useQuery(routes.userList, { + const { data: assignedUser } = useTanStackQueryInstead(routes.userList, { query: { id: qParams.assigned_to }, prefetch: !!qParams.assigned_to, }); diff --git a/src/components/Shifting/ShiftingFilters.tsx b/src/components/Shifting/ShiftingFilters.tsx index f73f42d5710..e382dd8c11e 100644 --- a/src/components/Shifting/ShiftingFilters.tsx +++ b/src/components/Shifting/ShiftingFilters.tsx @@ -26,7 +26,7 @@ import { } from "@/common/constants"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { dateQueryString, parsePhoneNumber } from "@/Utils/utils"; const getDate = (value: any) => @@ -67,45 +67,54 @@ export default function ListFilter(props: any) { breathlessness_level: filter.breathlessness_level || "", }); - const { loading: isOriginLoading } = useQuery(routes.getAnyFacility, { - prefetch: filter.origin_facility ? true : false, - pathParams: { id: filter.origin_facility }, - onResponse: ({ res, data }) => { - if (res && data) { - setFilterState({ - origin_facility_ref: filter.origin_facility ? "" : data, - }); - } + const { loading: isOriginLoading } = useTanStackQueryInstead( + routes.getAnyFacility, + { + prefetch: filter.origin_facility ? true : false, + pathParams: { id: filter.origin_facility }, + onResponse: ({ res, data }) => { + if (res && data) { + setFilterState({ + origin_facility_ref: filter.origin_facility ? "" : data, + }); + } + }, }, - }); + ); - const { loading: isShiftingLoading } = useQuery(routes.getAnyFacility, { - prefetch: filter.shifting_approving_facility ? true : false, - pathParams: { id: filter.shifting_approving_facility }, - onResponse: ({ res, data }) => { - if (res && data) { - setFilterState({ - shifting_approving_facility_ref: filter.shifting_approving_facility - ? "" - : data, - }); - } + const { loading: isShiftingLoading } = useTanStackQueryInstead( + routes.getAnyFacility, + { + prefetch: filter.shifting_approving_facility ? true : false, + pathParams: { id: filter.shifting_approving_facility }, + onResponse: ({ res, data }) => { + if (res && data) { + setFilterState({ + shifting_approving_facility_ref: filter.shifting_approving_facility + ? "" + : data, + }); + } + }, }, - }); + ); - const { loading: isAssignedLoading } = useQuery(routes.getAnyFacility, { - prefetch: filter.assigned_facility ? true : false, - pathParams: { id: filter.assigned_facility }, - onResponse: ({ res, data }) => { - if (res && data) { - setFilterState({ - assigned_facility_ref: filter.assigned_facility ? "" : data, - }); - } + const { loading: isAssignedLoading } = useTanStackQueryInstead( + routes.getAnyFacility, + { + prefetch: filter.assigned_facility ? true : false, + pathParams: { id: filter.assigned_facility }, + onResponse: ({ res, data }) => { + if (res && data) { + setFilterState({ + assigned_facility_ref: filter.assigned_facility ? "" : data, + }); + } + }, }, - }); + ); - useQuery(routes.userList, { + useTanStackQueryInstead(routes.userList, { query: { id: filter.assigned_to }, prefetch: filter.assigned_to ? true : false, onResponse: ({ res, data }) => { diff --git a/src/components/Shifting/ShiftingList.tsx b/src/components/Shifting/ShiftingList.tsx index f9727bdd819..3bf071f1cc2 100644 --- a/src/components/Shifting/ShiftingList.tsx +++ b/src/components/Shifting/ShiftingList.tsx @@ -18,7 +18,7 @@ import useFilters from "@/hooks/useFilters"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import ShiftingTable from "./ShiftingTable"; @@ -41,7 +41,7 @@ export default function ListView() { data: shiftData, loading, refetch: fetchData, - } = useQuery(routes.listShiftRequests, { + } = useTanStackQueryInstead(routes.listShiftRequests, { query: formatFilter({ ...qParams, offset: (qParams.page ? qParams.page - 1 : 0) * resultsPerPage, diff --git a/src/components/Symptoms/SymptomsBuilder.tsx b/src/components/Symptoms/SymptomsBuilder.tsx index 0a004b0e742..fdd771b3f3e 100644 --- a/src/components/Symptoms/SymptomsBuilder.tsx +++ b/src/components/Symptoms/SymptomsBuilder.tsx @@ -19,7 +19,7 @@ import useSlug from "@/hooks/useSlug"; import { Success } from "@/Utils/Notifications"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { Writable } from "@/Utils/types"; import { classNames, dateQueryString } from "@/Utils/utils"; @@ -79,7 +79,7 @@ export const EncounterSymptomsBuilder = (props: { const consultationId = useSlug("consultation"); const [isProcessing, setIsProcessing] = useState(false); - const { data, loading, refetch } = useQuery(SymptomsApi.list, { + const { data, loading, refetch } = useTanStackQueryInstead(SymptomsApi.list, { pathParams: { consultationId }, query: { limit: 100 }, }); diff --git a/src/components/Symptoms/SymptomsCard.tsx b/src/components/Symptoms/SymptomsCard.tsx index 2f3287a67e3..fafacaa39da 100644 --- a/src/components/Symptoms/SymptomsCard.tsx +++ b/src/components/Symptoms/SymptomsCard.tsx @@ -8,13 +8,13 @@ import { groupAndSortSymptoms } from "@/components/Symptoms/utils"; import useSlug from "@/hooks/useSlug"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; // TODO: switch to list from events as timeline view instead once filter event by event type name is done const EncounterSymptomsCard = () => { const consultationId = useSlug("consultation"); - const { data } = useQuery(SymptomsApi.list, { + const { data } = useTanStackQueryInstead(SymptomsApi.list, { pathParams: { consultationId }, query: { limit: 100 }, }); diff --git a/src/components/Users/LinkedFacilities.tsx b/src/components/Users/LinkedFacilities.tsx index 18d520abca3..e582b81dec0 100644 --- a/src/components/Users/LinkedFacilities.tsx +++ b/src/components/Users/LinkedFacilities.tsx @@ -22,7 +22,7 @@ import AuthorizeFor from "@/Utils/AuthorizeFor"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import ButtonV2 from "../Common/ButtonV2"; @@ -58,25 +58,28 @@ export default function LinkedFacilities({ const isCurrentUser = userData.username === authUser.username; - const { refetch: refetchUserFacilities } = useQuery(routes.userListFacility, { - pathParams: { username: userData.username }, - query: { limit: 36 }, - onResponse({ res, data }) { - if (res?.status === 200 && data) { - let userFacilities = data?.results; - if (userData.home_facility_object) { - const homeFacility = data?.results.find( - (facility) => facility.id === userData.home_facility_object?.id, - ); - userFacilities = userFacilities.filter( - (facility) => facility.id !== homeFacility?.id, - ); - setHomeFacility(homeFacility); + const { refetch: refetchUserFacilities } = useTanStackQueryInstead( + routes.userListFacility, + { + pathParams: { username: userData.username }, + query: { limit: 36 }, + onResponse({ res, data }) { + if (res?.status === 200 && data) { + let userFacilities = data?.results; + if (userData.home_facility_object) { + const homeFacility = data?.results.find( + (facility) => facility.id === userData.home_facility_object?.id, + ); + userFacilities = userFacilities.filter( + (facility) => facility.id !== homeFacility?.id, + ); + setHomeFacility(homeFacility); + } + setUserFacilities(userFacilities); } - setUserFacilities(userFacilities); - } + }, }, - }); + ); const handleOnClick = (type: string, selectedFacility: FacilityModel) => { switch (type) { diff --git a/src/components/Users/LinkedSkills.tsx b/src/components/Users/LinkedSkills.tsx index 8baa5a1b06b..399236d3fec 100644 --- a/src/components/Users/LinkedSkills.tsx +++ b/src/components/Users/LinkedSkills.tsx @@ -12,7 +12,7 @@ import AuthorizeFor from "@/Utils/AuthorizeFor"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import UnlinkSkillDialog from "./UnlinkSkillDialog"; import { SkillModel } from "./models"; @@ -30,7 +30,7 @@ export default function LinkedSkills({ username }: { username: string }) { const [selectedSkill, setSelectedSkill] = useState(null); const { t } = useTranslation(); - const { data: skills, refetch: refetchUserSkills } = useQuery( + const { data: skills, refetch: refetchUserSkills } = useTanStackQueryInstead( routes.userListSkill, { pathParams: { username }, diff --git a/src/components/Users/ManageUsers.tsx b/src/components/Users/ManageUsers.tsx index 5b441e76150..0851a186728 100644 --- a/src/components/Users/ManageUsers.tsx +++ b/src/components/Users/ManageUsers.tsx @@ -25,7 +25,7 @@ import { USER_TYPES } from "@/common/constants"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { classNames } from "@/Utils/utils"; export default function ManageUsers() { @@ -49,14 +49,16 @@ export default function ManageUsers() { : USER_TYPES.slice(0, userIndex + 1); const [activeTab, setActiveTab] = useState(0); - const { data: homeFacilityData } = useQuery(routes.getAnyFacility, { - pathParams: { id: qParams.home_facility }, - prefetch: !!qParams.home_facility && qParams.home_facility !== "NONE", - }); - - const { data: userListData, loading: userListLoading } = useQuery( - routes.userList, + const { data: homeFacilityData } = useTanStackQueryInstead( + routes.getAnyFacility, { + pathParams: { id: qParams.home_facility }, + prefetch: !!qParams.home_facility && qParams.home_facility !== "NONE", + }, + ); + + const { data: userListData, loading: userListLoading } = + useTanStackQueryInstead(routes.userList, { query: { limit: resultsPerPage.toString(), offset: ( @@ -72,8 +74,7 @@ export default function ManageUsers() { home_facility: qParams.home_facility, last_active_days: qParams.last_active_days, }, - }, - ); + }); useEffect(() => { if (!qParams.state && qParams.district) { @@ -84,13 +85,11 @@ export default function ManageUsers() { } }, [advancedFilter, qParams]); - const { data: districtData, loading: districtDataLoading } = useQuery( - routes.getDistrict, - { + const { data: districtData, loading: districtDataLoading } = + useTanStackQueryInstead(routes.getDistrict, { prefetch: !!qParams.district, pathParams: { id: qParams.district }, - }, - ); + }); const addUser = ( { loading: userDataLoading, data: userData, refetch: refetchUserData, - } = useQuery(routes.getUserDetails, { + } = useTanStackQueryInstead(routes.getUserDetails, { pathParams: { username: username ?? "", }, @@ -362,20 +362,23 @@ const UserAddEditForm = (props: UserProps) => { ...STAFF_OR_NURSE_USER, ].includes(state.form.user_type ?? ""); - const { loading: isDistrictLoading } = useQuery(routes.getDistrictByState, { - prefetch: !!(selectedStateId > 0), - pathParams: { id: selectedStateId.toString() }, - onResponse: (result) => { - if (!result || !result.res || !result.data) return; - if (userIndex <= USER_TYPES.indexOf("DistrictAdmin")) { - setDistricts([authUser.district_object!]); - } else { - setDistricts(result.data); - } + const { loading: isDistrictLoading } = useTanStackQueryInstead( + routes.getDistrictByState, + { + prefetch: !!(selectedStateId > 0), + pathParams: { id: selectedStateId.toString() }, + onResponse: (result) => { + if (!result || !result.res || !result.data) return; + if (userIndex <= USER_TYPES.indexOf("DistrictAdmin")) { + setDistricts([authUser.district_object!]); + } else { + setDistricts(result.data); + } + }, }, - }); + ); - const { loading: isLocalbodyLoading } = useQuery( + const { loading: isLocalbodyLoading } = useTanStackQueryInstead( routes.getAllLocalBodyByDistrict, { prefetch: !!(selectedDistrictId > 0), @@ -391,16 +394,19 @@ const UserAddEditForm = (props: UserProps) => { }, ); - const { loading: isStateLoading } = useQuery(routes.statesList, { - onResponse: (result) => { - if (!result || !result.res || !result.data) return; - if (userIndex <= USER_TYPES.indexOf("StateAdmin")) { - setStates([authUser.state_object!]); - } else { - setStates(result.data.results); - } + const { loading: isStateLoading } = useTanStackQueryInstead( + routes.statesList, + { + onResponse: (result) => { + if (!result || !result.res || !result.data) return; + if (userIndex <= USER_TYPES.indexOf("StateAdmin")) { + setStates([authUser.state_object!]); + } else { + setStates(result.data.results); + } + }, }, - }); + ); const handleDateChange = ( event: FieldChangeEvent, diff --git a/src/components/Users/UserAvatar.tsx b/src/components/Users/UserAvatar.tsx index c186039951e..db3620b34aa 100644 --- a/src/components/Users/UserAvatar.tsx +++ b/src/components/Users/UserAvatar.tsx @@ -16,7 +16,7 @@ import { showAvatarEdit } from "@/Utils/permissions"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; import uploadFile from "@/Utils/request/uploadFile"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { formatDisplayName, sleep } from "@/Utils/utils"; export default function UserAvatar({ username }: { username: string }) { @@ -28,7 +28,7 @@ export default function UserAvatar({ username }: { username: string }) { data: userData, loading: isLoading, refetch: refetchUserData, - } = useQuery(routes.getUserDetails, { + } = useTanStackQueryInstead(routes.getUserDetails, { pathParams: { username: username, }, diff --git a/src/components/Users/UserFilter.tsx b/src/components/Users/UserFilter.tsx index 30ddd90f939..2899f7b69cc 100644 --- a/src/components/Users/UserFilter.tsx +++ b/src/components/Users/UserFilter.tsx @@ -20,7 +20,7 @@ import { import * as Notify from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { parsePhoneNumber } from "@/Utils/utils"; const parsePhoneNumberForFilterParam = (phoneNumber: string) => { @@ -46,7 +46,7 @@ export default function UserFilter(props: any) { last_active_days: filter.last_active_days || "", }); - useQuery(routes.getAnyFacility, { + useTanStackQueryInstead(routes.getAnyFacility, { pathParams: { id: filter.home_facility }, prefetch: !!filter.home_facility && filter.home_facility !== "NONE", onResponse: ({ data }) => setFilterState({ home_facility_ref: data }), diff --git a/src/components/Users/UserHome.tsx b/src/components/Users/UserHome.tsx index dea75598ec9..8c12ad2c561 100644 --- a/src/components/Users/UserHome.tsx +++ b/src/components/Users/UserHome.tsx @@ -17,7 +17,7 @@ import useAuthUser from "@/hooks/useAuthUser"; import * as Notification from "@/Utils/Notifications"; import { editUserPermissions } from "@/Utils/permissions"; import routes from "@/Utils/request/api"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { classNames, formatName, keysOf } from "@/Utils/utils"; export interface UserHomeProps { @@ -39,7 +39,7 @@ export default function UserHome(props: UserHomeProps) { username = authUser.username; } - const { loading, refetch: refetchUserDetails } = useQuery( + const { loading, refetch: refetchUserDetails } = useTanStackQueryInstead( routes.getUserDetails, { pathParams: { diff --git a/src/components/Users/UserProfile.tsx b/src/components/Users/UserProfile.tsx index 7e8dff2aa84..4dd98635510 100644 --- a/src/components/Users/UserProfile.tsx +++ b/src/components/Users/UserProfile.tsx @@ -1,5 +1,5 @@ import careConfig from "@careConfig"; -import { FormEvent, useReducer, useState } from "react"; +import { FormEvent, useEffect, useReducer, useState } from "react"; import { useTranslation } from "react-i18next"; import CareIcon from "@/CAREUI/icons/CareIcon"; @@ -34,7 +34,7 @@ import dayjs from "@/Utils/dayjs"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; import uploadFile from "@/Utils/request/uploadFile"; -import useQuery from "@/Utils/request/useQuery"; +import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { dateQueryString, formatDate, @@ -159,47 +159,38 @@ export default function UserProfile() { }); const [showEdit, setShowEdit] = useState(false); - const { - data: userData, - loading: isUserLoading, - refetch: refetchUserData, - } = useQuery(routes.currentUser, { - onResponse: (result) => { - if (!result || !result.res || !result.data) return; - const formData: EditForm = { - firstName: result.data.first_name, - lastName: result.data.last_name, - date_of_birth: result.data.date_of_birth || null, - gender: result.data.gender || "Male", - email: result.data.email, - video_connect_link: result.data.video_connect_link, - phoneNumber: result.data.phone_number?.toString() || "", - altPhoneNumber: result.data.alt_phone_number?.toString() || "", - user_type: result.data.user_type, - qualification: result.data.qualification, - doctor_experience_commenced_on: dayjs().diff( - dayjs(result.data.doctor_experience_commenced_on), - "years", - ), - doctor_medical_council_registration: - result.data.doctor_medical_council_registration, - weekly_working_hours: result.data.weekly_working_hours, - }; - dispatch({ - type: "set_form", - form: formData, - }); - setDirty(false); - }, - }); + useEffect(() => { + const formData: EditForm = { + firstName: authUser.first_name, + lastName: authUser.last_name, + date_of_birth: authUser.date_of_birth || null, + gender: authUser.gender || "Male", + email: authUser.email, + video_connect_link: authUser.video_connect_link, + phoneNumber: authUser.phone_number?.toString() || "", + altPhoneNumber: authUser.alt_phone_number?.toString() || "", + user_type: authUser.user_type, + qualification: authUser.qualification, + doctor_experience_commenced_on: dayjs().diff( + dayjs(authUser.doctor_experience_commenced_on), + "years", + ), + doctor_medical_council_registration: + authUser.doctor_medical_council_registration, + weekly_working_hours: authUser.weekly_working_hours, + }; + dispatch({ + type: "set_form", + form: formData, + }); + setDirty(false); + }, [authUser]); - const { data: skillsView, loading: isSkillsLoading } = useQuery( - routes.userListSkill, - { + const { data: skillsView, loading: isSkillsLoading } = + useTanStackQueryInstead(routes.userListSkill, { pathParams: { username: authUser.username }, - }, - ); + }); const validatePassword = (password: string) => { const rules = [ @@ -432,13 +423,13 @@ export default function UserProfile() { Notification.Success({ msg: "Details updated successfully", }); - await refetchUserData(); + await refetchUser(); setShowEdit(false); } } }; - const isLoading = isUserLoading || isSkillsLoading; + const isLoading = isSkillsLoading; if (isLoading) { return ; @@ -559,7 +550,7 @@ export default function UserProfile() { setEditAvatar(false)} @@ -573,17 +564,17 @@ export default function UserProfile() {
setEditAvatar(!editAvatar)} className="h-20 w-20" />

- {authUser?.first_name} {authUser?.last_name} + {authUser.first_name} {authUser.last_name}

- @{authUser?.username} + @{authUser.username}

@@ -613,7 +604,7 @@ export default function UserProfile() { {t("username")}
- {userData?.username || "-"} + {authUser.username || "-"}
- {userData?.phone_number || "-"} + {authUser.phone_number || "-"}
@@ -636,7 +627,7 @@ export default function UserProfile() { {t("whatsapp_number")}
- {userData?.alt_phone_number || "-"} + {authUser.alt_phone_number || "-"}
- {userData?.email || "-"} + {authUser.email || "-"}
- {userData?.first_name || "-"} + {authUser.first_name || "-"}
- {userData?.last_name || "-"} + {authUser.last_name || "-"}
- {userData?.date_of_birth - ? formatDate(userData?.date_of_birth) + {authUser.date_of_birth + ? formatDate(authUser.date_of_birth) : "-"}
@@ -691,7 +682,7 @@ export default function UserProfile() {
- {userData?.user_type || "-"} + {authUser.user_type || "-"}
@@ -699,7 +690,7 @@ export default function UserProfile() { {t("gender")}
- {userData?.gender || "-"} + {authUser.gender || "-"}
@@ -707,7 +698,7 @@ export default function UserProfile() { {t("local_body")}
- {userData?.local_body_object?.name || "-"} + {authUser.local_body_object?.name || "-"}
@@ -715,7 +706,7 @@ export default function UserProfile() { {t("district")}
- {userData?.district_object?.name || "-"} + {authUser.district_object?.name || "-"}
@@ -723,7 +714,7 @@ export default function UserProfile() { {t("state")}
- {userData?.state_object?.name || "-"} + {authUser.state_object?.name || "-"}
@@ -757,7 +748,7 @@ export default function UserProfile() { {t("average_weekly_working_hours")}
- {userData?.weekly_working_hours ?? "-"} + {authUser.weekly_working_hours ?? "-"}
- {userData?.video_connect_link ? ( + {authUser.video_connect_link ? ( - {userData?.video_connect_link} + {authUser.video_connect_link} ) : ( "-" From 8a3a59fdb0f453ee14b7236995106bca4091eb20 Mon Sep 17 00:00:00 2001 From: Rithvik Nishad Date: Thu, 12 Dec 2024 11:34:48 +0000 Subject: [PATCH 13/21] Sample Test Details: Fix Padding and enclose status and result with i18n (#9387) --- src/components/Patient/SampleDetails.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/Patient/SampleDetails.tsx b/src/components/Patient/SampleDetails.tsx index 6cede48bfa5..f0e5f0039e5 100644 --- a/src/components/Patient/SampleDetails.tsx +++ b/src/components/Patient/SampleDetails.tsx @@ -265,7 +265,7 @@ export const SampleDetails = ({ id }: DetailRoute) => { const renderFlow = (flow: FlowModel) => { return ( -
+
{t("status")}:{" "} @@ -323,16 +323,16 @@ export const SampleDetails = ({ id }: DetailRoute) => {
{t("status")}:{" "}
- - {sampleDetails?.status} + + {t(`SAMPLE_TEST_HISTORY__${sampleDetails?.status}`)}
{t("result")}:{" "}
- - {sampleDetails?.result} + + {t(`SAMPLE_TEST_RESULT__${sampleDetails?.result}`)}
@@ -540,7 +540,7 @@ export const SampleDetails = ({ id }: DetailRoute) => {

{t("sample_test_history")}

{sampleDetails?.flow && sampleDetails.flow.map((flow: FlowModel) => ( -
+
{renderFlow(flow)}
))} From ae8ac6fba08ee4ea0914fe528beef0a5f4c62c08 Mon Sep 17 00:00:00 2001 From: Noufal Rahim <120470585+noufalrahim@users.noreply.github.com> Date: Thu, 12 Dec 2024 20:10:42 +0530 Subject: [PATCH 14/21] fix: fixed enter key issue (#9396) --- src/components/Form/Form.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/Form/Form.tsx b/src/components/Form/Form.tsx index 5a3bf552b26..18f190ccc3c 100644 --- a/src/components/Form/Form.tsx +++ b/src/components/Form/Form.tsx @@ -98,6 +98,11 @@ const Form = ({ return (
{ + if (e.key === "Enter") { + handleSubmit(e); + } + }} className={classNames( "mx-auto w-full", !props.noPadding && "px-8 py-5 md:px-16 md:py-11", From ed48ece8e1c243138e3d73056094e0905f861580 Mon Sep 17 00:00:00 2001 From: Aditya Jindal Date: Thu, 12 Dec 2024 21:50:05 +0530 Subject: [PATCH 15/21] Fix: Added location for linked facility (#9383) --- src/components/Users/LinkedFacilities.tsx | 61 +++++++++++++++-------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/src/components/Users/LinkedFacilities.tsx b/src/components/Users/LinkedFacilities.tsx index e582b81dec0..4c75c885ca2 100644 --- a/src/components/Users/LinkedFacilities.tsx +++ b/src/components/Users/LinkedFacilities.tsx @@ -3,6 +3,7 @@ import { useTranslation } from "react-i18next"; import CareIcon from "@/CAREUI/icons/CareIcon"; +import { Button } from "@/components/ui/button"; import { DropdownMenu, DropdownMenuContent, @@ -24,8 +25,6 @@ import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; import useTanStackQueryInstead from "@/Utils/request/useQuery"; -import ButtonV2 from "../Common/ButtonV2"; - const initModalProps: { selectedFacility?: FacilityModel; type: string; @@ -201,11 +200,22 @@ export default function LinkedFacilities({ return (
-
-
{facility.name}
+
+
+ {facility.name} + {facility.district_object?.name && ( +
+ {facility.district_object?.name} + {facility.district_object?.name && + facility.state_object?.name && + ", "} + {facility.state_object?.name} +
+ )} +
-
- +
+
@@ -244,12 +254,21 @@ export default function LinkedFacilities({ id={`facility_${homeFacility.id}`} key={`facility_${homeFacility.id}`} > -
-
+
+
{homeFacility.name} + {homeFacility.district_object?.name && ( +
+ {homeFacility.district_object?.name} + {homeFacility.district_object?.name && + homeFacility.state_object?.name && + ", "} + {homeFacility.state_object?.name} +
+ )}
{(authorizeForHomeFacility || isCurrentUser) && ( -
+
)} @@ -280,7 +299,7 @@ export default function LinkedFacilities({ /> )}
-
+
- linkFacility(userData.username, facility)} disabled={!authorizeForHomeFacility} - tooltip={ - !authorizeForHomeFacility - ? t("contact_your_admin_to_add_facilities") - : undefined - } > {t("add_facility")} - +
{homeFacility && (

{t("home_facility")}

-
+
{renderHomeFacilityButton(homeFacility)}
)} + {userFacilities && userFacilities.length > 0 && (

{t("linked_facilities")}

{userFacilities.map((facility: FacilityModel) => { if (homeFacility?.id === facility.id) { From ead041beb1f4cd2e5f7f51d4ee53d05a250b4ce5 Mon Sep 17 00:00:00 2001 From: Aditya Jindal Date: Thu, 12 Dec 2024 22:56:50 +0530 Subject: [PATCH 16/21] Fix: Allergy count to Updated to has allergies text (#9399) --- public/locale/en.json | 1 + src/components/Patient/PatientHome.tsx | 15 ++++++++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/public/locale/en.json b/public/locale/en.json index 4fb925ac941..4b262e61d10 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -794,6 +794,7 @@ "get_tests": "Get Tests", "goal": "Our goal is to continuously improve the quality and accessibility of public healthcare services using digital tools.", "granted_on": "Granted On", + "has_allergies": "Has Allergies", "has_domestic_healthcare_support": "Has domestic healthcare support?", "has_sari": "Has SARI (Severe Acute Respiratory illness)?", "health-profile": "Health Profile", diff --git a/src/components/Patient/PatientHome.tsx b/src/components/Patient/PatientHome.tsx index 48d754d6d26..7ae439fa80b 100644 --- a/src/components/Patient/PatientHome.tsx +++ b/src/components/Patient/PatientHome.tsx @@ -362,13 +362,14 @@ export const PatientHome = (props: { text={t("TELEMEDICINE")} /> )} - {patientData.allergies && ( - - )} + {patientData.allergies && + patientData.allergies.trim().length > 0 && ( + + )}
From 2611a322d9633631e2213d04274aa71ccb5c8965 Mon Sep 17 00:00:00 2001 From: Jacob John Jeevan <40040905+Jacobjeevan@users.noreply.github.com> Date: Fri, 13 Dec 2024 12:11:57 +0530 Subject: [PATCH 17/21] User Creation Form Bug Fix (#9404) --- src/components/Users/UserAddEditForm.tsx | 2 +- src/components/Users/UserFormValidations.tsx | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/Users/UserAddEditForm.tsx b/src/components/Users/UserAddEditForm.tsx index c0f75dbe850..00793ce8fff 100644 --- a/src/components/Users/UserAddEditForm.tsx +++ b/src/components/Users/UserAddEditForm.tsx @@ -1179,7 +1179,7 @@ const UserAddEditForm = (props: UserProps) => { )} )} - {includedFields?.includes("local_body") && ( + {showLocalbody && includedFields?.includes("local_body") && ( <> {isLocalbodyLoading ? ( diff --git a/src/components/Users/UserFormValidations.tsx b/src/components/Users/UserFormValidations.tsx index a5af4549803..c59d4a4bd5c 100644 --- a/src/components/Users/UserFormValidations.tsx +++ b/src/components/Users/UserFormValidations.tsx @@ -50,8 +50,6 @@ export const newUserFields: Array = [ "qualification", "doctor_experience_commenced_on", "doctor_medical_council_registration", - "weekly_working_hours", - "video_connect_link", ]; export const editUserFields: Array = [ From 05e8f4ca9d4ad8eb31167751ff1f411fabe43098 Mon Sep 17 00:00:00 2001 From: Amjith Titus Date: Fri, 13 Dec 2024 18:10:56 +0530 Subject: [PATCH 18/21] Util function for cleaner usage of TanStack useQuery (#9395) ---- Co-authored-by: rithviknishad --- src/App.tsx | 12 ++- src/Utils/request/README.md | 137 +++++++++++++++++++++--------- src/Utils/request/errorHandler.ts | 54 ++++++++++++ src/Utils/request/query.ts | 56 ++++++++++++ src/Utils/request/queryError.ts | 24 ++++++ src/Utils/request/request.ts | 2 +- src/Utils/request/types.ts | 8 ++ 7 files changed, 251 insertions(+), 42 deletions(-) create mode 100644 src/Utils/request/errorHandler.ts create mode 100644 src/Utils/request/query.ts create mode 100644 src/Utils/request/queryError.ts diff --git a/src/App.tsx b/src/App.tsx index c91849de559..b4d1a1570a9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,8 @@ -import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { + QueryCache, + QueryClient, + QueryClientProvider, +} from "@tanstack/react-query"; import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; import { Suspense } from "react"; @@ -12,17 +16,21 @@ import AuthUserProvider from "@/Providers/AuthUserProvider"; import HistoryAPIProvider from "@/Providers/HistoryAPIProvider"; import Routers from "@/Routers"; import { FeatureFlagsProvider } from "@/Utils/featureFlags"; +import { handleQueryError } from "@/Utils/request/errorHandler"; import { PubSubProvider } from "./Utils/pubsubContext"; const queryClient = new QueryClient({ defaultOptions: { queries: { - retry: 3, + retry: 2, refetchOnWindowFocus: false, staleTime: 5 * 60 * 1000, // 5 minutes }, }, + queryCache: new QueryCache({ + onError: handleQueryError, + }), }); const App = () => { diff --git a/src/Utils/request/README.md b/src/Utils/request/README.md index 0780d3149f6..3c1279e1554 100644 --- a/src/Utils/request/README.md +++ b/src/Utils/request/README.md @@ -4,41 +4,108 @@ CARE now uses TanStack Query (formerly React Query) as its data fetching solutio ## Using TanStack Query (Recommended for new code) -For new API integrations, we recommend using TanStack Query directly: +For new API integrations, we recommend using TanStack Query with `query` utility function. This is a wrapper around `fetch` that works seamlessly with TanStack Query. It handles response parsing, error handling, setting headers, and more. ```tsx import { useQuery } from "@tanstack/react-query"; -import request from "@/Utils/request/request"; -import FooRoutes from "@foo/routes"; +import query from "@/Utils/request/query"; -export default function FooDetails({ id }) { - const { data, isLoading, error } = useQuery({ - queryKey: [FooRoutes.getFoo.path, id], - queryFn: async () => { - const response = await request(FooRoutes.getFoo, { - pathParams: { id } - }); - return response.data; - } +export default function UserProfile() { + const { data, isLoading } = useQuery({ + queryKey: [routes.users.current.path], + queryFn: query(routes.users.current) }); if (isLoading) return ; - if (error) return ; + return
{data?.name}
; +} - return ( -
- {data.id} - {data.name} -
- ); +// With path parameters +function PatientDetails({ id }: { id: string }) { + const { data } = useQuery({ + queryKey: ['patient', id], + queryFn: query(routes.patient.get, { + pathParams: { id } + }) + }); + + return
{data?.name}
; +} + +// With query parameters +function SearchMedicines() { + const { data } = useQuery({ + queryKey: ['medicines', 'paracetamol'], + queryFn: query(routes.medicine.search, { + queryParams: { search: 'paracetamol' } + }) + }); + + return ; +} + +// When you need response status/error handling +function FacilityDetails({ id }: { id: string }) { + const { data, isLoading } = useQuery({ + queryKey: ["facility", id], + queryFn: query(routes.getFacility, { + pathParams: { id }, + silent: true + }) + }); + + if (isLoading) return ; + return
{data?.name}
; +} + +### query + +`query` is our wrapper around fetch that works seamlessly with TanStack Query. It: +- Handles response parsing (JSON, text, blobs). +- Constructs proper error objects. +- Sets the headers appropriately. +- Integrates with our global error handling. + +```typescript +interface QueryOptions { + pathParams?: Record; // URL parameters + queryParams?: Record; // Query string parameters + silent?: boolean; // Suppress error notifications } + +// Basic usage +useQuery({ + queryKey: ["users"], + queryFn: query(routes.users.list) +}); + +// With parameters +useQuery({ + queryKey: ["user", id], + queryFn: query(routes.users.get, { + pathParams: { id }, + queryParams: { include: "details" }, + silent: true // Optional: suppress error notifications + }) +}); ``` +### Error Handling + +All API errors are now handled globally. Common scenarios like: + +- Session expiry -> Redirects to /session-expired +- Bad requests (400/406) -> Shows error notification +are automatically handled. + +Use the `silent: true` option to suppress error notifications for specific queries. + ## Migration Guide & Reference ### Understanding the Transition Our codebase contains two patterns for data fetching: + 1. Legacy pattern using `useTanStackQueryInstead` (wrapper around TanStack Query) 2. Modern pattern using TanStack Query directly @@ -60,12 +127,9 @@ function LegacyComponent({ id }) { function ModernComponent({ id }) { const { data, isLoading, error, refetch } = useQuery({ queryKey: [UserRoutes.getUser.path, id], - queryFn: async () => { - const response = await request(UserRoutes.getUser, { - pathParams: { id } - }); - return response.data; - }, + queryFn: query(UserRoutes.getUser, { + pathParams: { id } + }), enabled: true, refetchOnWindowFocus: false }); @@ -100,7 +164,7 @@ useTanStackQueryInstead(route, { prefetch: shouldFetch }) // Modern useQuery({ queryKey: [route.path], - queryFn: async () => (await request(route)).data, + queryFn: query(route), enabled: shouldFetch }) ``` @@ -116,13 +180,10 @@ useTanStackQueryInstead(route, { // Modern useQuery({ queryKey: [route.path, id, filter], - queryFn: async () => { - const response = await request(route, { - pathParams: { id }, - query: { filter } - }); - return response.data; - } + queryFn: query(route, { + pathParams: { id }, + queryParams: { filter } + }) }) ``` @@ -135,12 +196,10 @@ if (res?.status === 403) handleForbidden(); // Modern useQuery({ queryKey: [route.path], - queryFn: async () => { - const response = await request(route); - if (response.res.status === 403) handleForbidden(); - return response.data; - }, - onError: (error) => handleError(error) + queryFn: query(route, { + silent: true // Optional: suppress error notifications + }) + // Error handling is now done globally }) ``` diff --git a/src/Utils/request/errorHandler.ts b/src/Utils/request/errorHandler.ts new file mode 100644 index 00000000000..68d7e4600bb --- /dev/null +++ b/src/Utils/request/errorHandler.ts @@ -0,0 +1,54 @@ +import { navigate } from "raviger"; + +import * as Notifications from "@/Utils/Notifications"; +import { QueryError } from "@/Utils/request/queryError"; + +export function handleQueryError(error: Error) { + if (error.name === "AbortError") { + return; + } + + if (!(error instanceof QueryError)) { + Notifications.Error({ msg: error.message || "Something went wrong!" }); + return; + } + + if (error.silent) { + return; + } + + const cause = error.cause; + + if (isSessionExpired(cause)) { + handleSessionExpired(); + return; + } + + if (isBadRequest(error)) { + Notifications.BadRequest({ errs: cause }); + return; + } + + Notifications.Error({ + msg: cause?.detail || "Something went wrong...!", + }); +} + +function isSessionExpired(error: QueryError["cause"]) { + return ( + // If Authorization header is not valid + error?.code === "token_not_valid" || + // If Authorization header is not provided + error?.detail === "Authentication credentials were not provided." + ); +} + +function handleSessionExpired() { + if (!location.pathname.startsWith("/session-expired")) { + navigate(`/session-expired?redirect=${window.location.href}`); + } +} + +function isBadRequest(error: QueryError) { + return error.status === 400 || error.status === 406; +} diff --git a/src/Utils/request/query.ts b/src/Utils/request/query.ts new file mode 100644 index 00000000000..3431f625728 --- /dev/null +++ b/src/Utils/request/query.ts @@ -0,0 +1,56 @@ +import careConfig from "@careConfig"; + +import { QueryError } from "@/Utils/request/queryError"; +import { getResponseBody } from "@/Utils/request/request"; +import { QueryOptions, Route } from "@/Utils/request/types"; +import { makeHeaders, makeUrl } from "@/Utils/request/utils"; + +async function queryRequest( + { path, method, noAuth }: Route, + options?: QueryOptions
, +): Promise { + const url = `${careConfig.apiUrl}${makeUrl(path, options?.queryParams, options?.pathParams)}`; + + const fetchOptions: RequestInit = { + method, + headers: makeHeaders(noAuth ?? false), + signal: options?.signal, + }; + + if (options?.body) { + fetchOptions.body = JSON.stringify(options.body); + } + + let res: Response; + + try { + res = await fetch(url, fetchOptions); + } catch { + throw new Error("Network Error"); + } + + const data = await getResponseBody(res); + + if (!res.ok) { + throw new QueryError({ + message: "Request Failed", + status: res.status, + silent: options?.silent ?? false, + cause: data as unknown as Record, + }); + } + + return data; +} + +/** + * Creates a TanStack Query compatible request function + */ +export default function query( + route: Route, + options?: QueryOptions, +) { + return ({ signal }: { signal: AbortSignal }) => { + return queryRequest(route, { ...options, signal }); + }; +} diff --git a/src/Utils/request/queryError.ts b/src/Utils/request/queryError.ts new file mode 100644 index 00000000000..cdfad312ef4 --- /dev/null +++ b/src/Utils/request/queryError.ts @@ -0,0 +1,24 @@ +type QueryErrorCause = Record | undefined; + +export class QueryError extends Error { + status: number; + silent: boolean; + cause?: QueryErrorCause; + + constructor({ + message, + status, + silent, + cause, + }: { + message: string; + status: number; + silent: boolean; + cause?: Record; + }) { + super(message, { cause }); + this.status = status; + this.silent = silent; + this.cause = cause; + } +} diff --git a/src/Utils/request/request.ts b/src/Utils/request/request.ts index 73bc9763f50..bd1cabc523c 100644 --- a/src/Utils/request/request.ts +++ b/src/Utils/request/request.ts @@ -61,7 +61,7 @@ export default async function request( return result; } -async function getResponseBody(res: Response): Promise { +export async function getResponseBody(res: Response): Promise { if (!(res.headers.get("content-length") !== "0")) { return null as TData; } diff --git a/src/Utils/request/types.ts b/src/Utils/request/types.ts index 668f937dbf0..20f095ae6fd 100644 --- a/src/Utils/request/types.ts +++ b/src/Utils/request/types.ts @@ -35,6 +35,14 @@ export interface RequestOptions { silent?: boolean; } +export interface QueryOptions { + pathParams?: Record; + queryParams?: Record; + body?: TBody; + silent?: boolean; + signal?: AbortSignal; +} + export interface PaginatedResponse { count: number; next: string | null; From c8963adf533f4e11b5a864934ae7e99fdd7a1eeb Mon Sep 17 00:00:00 2001 From: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> Date: Sat, 14 Dec 2024 06:16:49 +0530 Subject: [PATCH 19/21] Fixed the date format in the user details page (#9409) --- cypress/e2e/users_spec/UsersManage.cy.ts | 2 +- package-lock.json | 9 ++++----- package.json | 2 +- src/components/Users/UserViewDetails.tsx | 8 +++----- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/cypress/e2e/users_spec/UsersManage.cy.ts b/cypress/e2e/users_spec/UsersManage.cy.ts index c7d237efb43..8d7ac8695c6 100644 --- a/cypress/e2e/users_spec/UsersManage.cy.ts +++ b/cypress/e2e/users_spec/UsersManage.cy.ts @@ -66,7 +66,7 @@ describe("Manage User", () => { manageUserPage.verifyEditUserDetails( "Devo", "Districto", - "8/11/1999", + "11/08/1999", "Female", ); }); diff --git a/package-lock.json b/package-lock.json index 106518926f4..41d7fcfff8c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,7 +40,7 @@ "clsx": "^2.1.1", "cmdk": "^1.0.4", "cross-env": "^7.0.3", - "cypress": "^13.16.1", + "cypress": "^13.16.0", "dayjs": "^1.11.13", "echarts": "^5.5.1", "echarts-for-react": "^3.0.2", @@ -7807,11 +7807,10 @@ "license": "MIT" }, "node_modules/cypress": { - "version": "13.16.1", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.16.1.tgz", - "integrity": "sha512-17FtCaz0cx7ssWYKXzGB0Vub8xHwpVPr+iPt2fHhLMDhVAPVrplD+rTQsZUsfb19LVBn5iwkEUFjQ1yVVJXsLA==", + "version": "13.16.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.16.0.tgz", + "integrity": "sha512-g6XcwqnvzXrqiBQR/5gN+QsyRmKRhls1y5E42fyOvsmU7JuY+wM6uHJWj4ZPttjabzbnRvxcik2WemR8+xT6FA==", "hasInstallScript": true, - "license": "MIT", "dependencies": { "@cypress/request": "^3.0.6", "@cypress/xvfb": "^1.2.4", diff --git a/package.json b/package.json index 7bc7e5c117b..15392d09410 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ "clsx": "^2.1.1", "cmdk": "^1.0.4", "cross-env": "^7.0.3", - "cypress": "^13.16.1", + "cypress": "^13.16.0", "dayjs": "^1.11.13", "echarts": "^5.5.1", "echarts-for-react": "^3.0.2", diff --git a/src/components/Users/UserViewDetails.tsx b/src/components/Users/UserViewDetails.tsx index 8b6fb40a1d3..9f4c78fbacf 100644 --- a/src/components/Users/UserViewDetails.tsx +++ b/src/components/Users/UserViewDetails.tsx @@ -1,5 +1,7 @@ import { useTranslation } from "react-i18next"; +import { formatDate } from "@/Utils/utils"; + import { UserModel } from "./models"; interface UserViewDetailsProps { @@ -77,11 +79,7 @@ export const BasicInfoDetails = ({ user }: UserViewDetailsProps) => { From f82dfa8c55dfba7d9471c84592073b19f7d87eb8 Mon Sep 17 00:00:00 2001 From: Bodhish Thomas Date: Sat, 14 Dec 2024 23:42:52 +0530 Subject: [PATCH 20/21] Remove Sample management system (#9425) Co-authored-by: Aakash Singh --- .../SampleTestAdvanceFilters.cy.ts | 38 -- .../sample_test_spec/SampleTestHomepage.cy.ts | 54 -- .../sample_test_spec/SampleTestRequest.cy.ts | 88 --- cypress/fixtures/external-result-sample.csv | 2 - cypress/pageobject/Sample/SampleTestCreate.ts | 116 ---- public/External-Results-Template.csv | 3 - public/locale/en.json | 12 +- public/locale/hi.json | 1 - src/Routers/AppRouter.tsx | 2 - src/Routers/routes/SampleRoutes.tsx | 24 - src/Utils/request/api.tsx | 41 +- src/common/constants.tsx | 49 -- src/components/Common/Breadcrumbs.tsx | 1 - src/components/Common/Sidebar/Sidebar.tsx | 1 - .../PatientDetailsTab/SampleTestHistory.tsx | 107 ---- .../Patient/PatientDetailsTab/index.tsx | 5 - src/components/Patient/PatientHome.tsx | 42 +- src/components/Patient/SampleDetails.tsx | 558 ------------------ src/components/Patient/SampleFilters.tsx | 131 ---- src/components/Patient/SamplePreview.tsx | 459 -------------- src/components/Patient/SampleTest.tsx | 350 ----------- src/components/Patient/SampleTestCard.tsx | 227 ------- src/components/Patient/SampleViewAdmin.tsx | 423 ------------- src/components/Patient/UpdateStatusDialog.tsx | 230 -------- src/components/Patient/models.tsx | 131 ---- src/hooks/useActiveLink.ts | 1 - 26 files changed, 4 insertions(+), 3092 deletions(-) delete mode 100644 cypress/e2e/sample_test_spec/SampleTestAdvanceFilters.cy.ts delete mode 100644 cypress/e2e/sample_test_spec/SampleTestHomepage.cy.ts delete mode 100644 cypress/e2e/sample_test_spec/SampleTestRequest.cy.ts delete mode 100644 cypress/fixtures/external-result-sample.csv delete mode 100644 cypress/pageobject/Sample/SampleTestCreate.ts delete mode 100644 public/External-Results-Template.csv delete mode 100644 src/Routers/routes/SampleRoutes.tsx delete mode 100644 src/components/Patient/PatientDetailsTab/SampleTestHistory.tsx delete mode 100644 src/components/Patient/SampleDetails.tsx delete mode 100644 src/components/Patient/SampleFilters.tsx delete mode 100644 src/components/Patient/SamplePreview.tsx delete mode 100644 src/components/Patient/SampleTest.tsx delete mode 100644 src/components/Patient/SampleTestCard.tsx delete mode 100644 src/components/Patient/SampleViewAdmin.tsx delete mode 100644 src/components/Patient/UpdateStatusDialog.tsx diff --git a/cypress/e2e/sample_test_spec/SampleTestAdvanceFilters.cy.ts b/cypress/e2e/sample_test_spec/SampleTestAdvanceFilters.cy.ts deleted file mode 100644 index 562eb22a75e..00000000000 --- a/cypress/e2e/sample_test_spec/SampleTestAdvanceFilters.cy.ts +++ /dev/null @@ -1,38 +0,0 @@ -import LoginPage from "pageobject/Login/LoginPage"; - -const loginPage = new LoginPage(); - -describe("Sample Filter", () => { - before(() => { - loginPage.loginByRole("districtAdmin"); - cy.saveLocalStorage(); - }); - - beforeEach(() => { - cy.restoreLocalStorage(); - cy.clearLocalStorage(/filters--.+/); - cy.awaitUrl("/sample"); - cy.contains("Advanced Filters").click(); - }); - - it("Filter by Status", () => { - cy.get("#status").click(); - cy.get("li[role='option']") - .contains(/^APPROVED$/) - .click(); - }); - - it("Filter by sample type", () => { - cy.get("#sample_type").click(); - cy.get("li[role='option']") - .contains(/^Biopsy$/) - .click(); - }); - - afterEach(() => { - cy.intercept(/\/api\/v1\/test_sample/).as("sample_filter"); - cy.contains("Apply").click(); - cy.wait("@sample_filter"); - cy.saveLocalStorage(); - }); -}); diff --git a/cypress/e2e/sample_test_spec/SampleTestHomepage.cy.ts b/cypress/e2e/sample_test_spec/SampleTestHomepage.cy.ts deleted file mode 100644 index 491da5ee7ad..00000000000 --- a/cypress/e2e/sample_test_spec/SampleTestHomepage.cy.ts +++ /dev/null @@ -1,54 +0,0 @@ -import LoginPage from "pageobject/Login/LoginPage"; - -const loginPage = new LoginPage(); - -describe("Sample List", () => { - before(() => { - loginPage.loginByRole("districtAdmin"); - cy.saveLocalStorage(); - }); - - beforeEach(() => { - cy.restoreLocalStorage(); - cy.clearLocalStorage(/filters--.+/); - cy.awaitUrl("/sample"); - }); - - it("Search by District name", () => { - cy.intercept(/\/api\/v1\/test_sample/).as("test_sample"); - cy.get("[name='district_name']").type("Test"); - cy.wait("@test_sample").its("response.statusCode").should("eq", 200); - cy.url().should("include", "Test"); - }); - - it("Search by Patient Name", () => { - cy.intercept(/\/api\/v1\/test_sample/).as("test_sample"); - cy.get("[name='patient_name']").type("Test"); - cy.wait("@test_sample").its("response.statusCode").should("eq", 200); - cy.url().should("include", "Test"); - }); - - it("Update Sample Status", () => { - cy.contains("UPDATE SAMPLE TEST STATUS").click(); - }); - - it("View Sample Details", () => { - cy.contains("Sample Details").click(); - }); - - it("Next/Previous Page", () => { - // only works for desktop mode - cy.get("button") - .should("contain", "Next") - .contains("Next") - .click({ force: true }); - cy.get("button") - .should("contain", "Previous") - .contains("Previous") - .click({ force: true }); - }); - - afterEach(() => { - cy.saveLocalStorage(); - }); -}); diff --git a/cypress/e2e/sample_test_spec/SampleTestRequest.cy.ts b/cypress/e2e/sample_test_spec/SampleTestRequest.cy.ts deleted file mode 100644 index a4b26d328e5..00000000000 --- a/cypress/e2e/sample_test_spec/SampleTestRequest.cy.ts +++ /dev/null @@ -1,88 +0,0 @@ -import LoginPage from "pageobject/Login/LoginPage"; -import { PatientConsultationPage } from "pageobject/Patient/PatientConsultation"; -import { PatientPage } from "pageobject/Patient/PatientCreation"; -import { SampleTestPage } from "pageobject/Sample/SampleTestCreate"; - -describe("Sample Test", () => { - const sampleTestPage = new SampleTestPage(); - const patientPage = new PatientPage(); - const loginPage = new LoginPage(); - const patientConsultationPage = new PatientConsultationPage(); - const patientName = "Dummy Patient Eleven"; - const sampleTestType = "BA/ETA"; - const icmrCategory = "Cat 0"; - const icmrLabel = "Test Icmr Label"; - const doctorName = "Dr John Doe"; - const atypicalDetails = "Patient showing unusual symptoms"; - const diagnosis = "Suspected respiratory infection"; - const etiologyIdentified = "Bacterial infection suspected"; - const differentialDiagnosis = "Possibly a viral infection"; - const fastTrackReason = - "The patient has a high risk of complications and requires immediate testing."; - const sampleTestStatus = "Request Submitted"; - const expectedSampleTestType = "ba/eta"; - const sampleTestResult = "Awaiting"; - - before(() => { - loginPage.loginByRole("districtAdmin"); - cy.saveLocalStorage(); - }); - - beforeEach(() => { - cy.restoreLocalStorage(); - cy.clearLocalStorage(/filters--.+/); - }); - - it("should request a new sample test", () => { - // Ensure patient list API is loaded before proceeding - cy.awaitUrl("/patients"); - patientPage.visitPatient(patientName); - patientConsultationPage.interceptPatientDetailsAPI(); - patientConsultationPage.clickPatientDetails(); - patientConsultationPage.verifyPatientDetailsResponse(); - // Visit SampleRequest Page - sampleTestPage.visitSampleRequestPage(); - // Fill Sample Test Request Form - sampleTestPage.selectSampleType(sampleTestType); - sampleTestPage.selectIcmrCategory(icmrCategory); - sampleTestPage.fillIcmrLabel(icmrLabel); - sampleTestPage.fillFastTrackReason(fastTrackReason); - sampleTestPage.fillDoctorName(doctorName); - sampleTestPage.fillAtypicalPresentation(atypicalDetails); - sampleTestPage.fillDiagnosis(diagnosis); - sampleTestPage.fillEtiology(etiologyIdentified); - sampleTestPage.fillDiffDiagnosis(differentialDiagnosis); - sampleTestPage.checkHasSari(); - sampleTestPage.checkHasAri(); - sampleTestPage.checkIsUnusualCourse(); - sampleTestPage.interceptSampleTestReq(); - // Submit the form and verify notification - cy.clickSubmitButton("Confirm your request to send sample for testing"); - sampleTestPage.verifySampleTestReq(); - cy.verifyNotification("Sample test created successfully"); - // Check the updated request history - sampleTestPage.checkRequestHistory( - sampleTestStatus, - expectedSampleTestType, - fastTrackReason, - sampleTestResult, - ); - // Checking Reflection on Sample Page - cy.awaitUrl("/sample"); - sampleTestPage.interceptGetSampleTestReq(); - sampleTestPage.searchPatientSample(patientName); - sampleTestPage.verifyGetSampleTestReq(); - sampleTestPage.verifyPatientName(patientName); - sampleTestPage.interceptGetSampleTestReq(); - sampleTestPage.clickOnSampleDetailsBtn(); - sampleTestPage.verifyGetSampleTestReq(); - sampleTestPage.verifyPatientTestDetails( - patientName, - fastTrackReason, - doctorName, - diagnosis, - differentialDiagnosis, - etiologyIdentified, - ); - }); -}); diff --git a/cypress/fixtures/external-result-sample.csv b/cypress/fixtures/external-result-sample.csv deleted file mode 100644 index 2905cdc1af3..00000000000 --- a/cypress/fixtures/external-result-sample.csv +++ /dev/null @@ -1,2 +0,0 @@ -District,SRF ID,Name,Age,Age in,Gender,Mobile Number,Address,Ward,Local Body,Local Body Type,Source,Sample Collection Date,Result Date,Test Type,Lab Name,Sample Type,Patient Status,Is Repeat,Patient Category,Result -Ernakulam,00/EKM/0000,Test Upload,24,years,m,8888888888,Upload test address,7,Poothrikka,grama panchayath,Secondary contact aparna,2020-10-14,2020-10-14,Antigen,Karothukuzhi Laboratory,Ag-SD_Biosensor_Standard_Q_COVID-19_Ag_detection_kit,Asymptomatic,NO,Cat 17: All individuals who wish to get themselves tested,Negative diff --git a/cypress/pageobject/Sample/SampleTestCreate.ts b/cypress/pageobject/Sample/SampleTestCreate.ts deleted file mode 100644 index 445d08732c3..00000000000 --- a/cypress/pageobject/Sample/SampleTestCreate.ts +++ /dev/null @@ -1,116 +0,0 @@ -export class SampleTestPage { - visitSampleRequestPage(): void { - cy.get("a").contains("Service Request").click(); - cy.verifyAndClickElement("#sample-request-btn", "Request Sample Test"); - cy.url().should("include", "/sample-test"); - } - - selectSampleType(option: string): void { - cy.clickAndSelectOption("#sample-type", option); - } - - selectIcmrCategory(option: string): void { - cy.clickAndSelectOption("#icmr-category", option); - } - - fillIcmrLabel(label: string): void { - cy.get("#icmr-label").should("be.visible").type(label); - } - - fillFastTrackReason(value: string): void { - cy.get("#is_fast_track").should("be.visible").check(); - cy.get("#fast_track").should("be.visible").type(value); - } - - fillDoctorName(value: string): void { - cy.get("#doctor_name").should("be.visible").type(value); - } - - fillAtypicalPresentation(value: string): void { - cy.get("#is_atypical_presentation").should("be.visible").check(); - cy.get("#atypical_presentation").should("be.visible").type(value); - } - - fillDiagnosis(value: string): void { - cy.get("#diagnosis").should("be.visible").type(value); - } - - fillEtiology(value: string): void { - cy.get("#etiology_identified").should("be.visible").type(value); - } - - fillDiffDiagnosis(value: string): void { - cy.get("#diff_diagnosis").should("be.visible").type(value); - } - - checkHasSari(): void { - cy.get("#has_sari").should("be.visible").check(); - } - - checkHasAri(): void { - cy.get("#has_ari").should("be.visible").check(); - } - - checkIsUnusualCourse(): void { - cy.get("#is_unusual_course").should("be.visible").check(); - } - - checkRequestHistory( - sampleTestStatus: string, - sampleTestType: string, - fastTrack: string, - sampleTestResult: string, - ): void { - cy.get("a").contains("Service Request").click(); - cy.verifyContentPresence("#sample-test-status", [sampleTestStatus]); - cy.verifyContentPresence("#sample-test-type", [sampleTestType]); - cy.verifyContentPresence("#sample-test-fast-track", [fastTrack]); - cy.verifyContentPresence("#sample-test-result", [sampleTestResult]); - } - - searchPatientSample(patientName: string): void { - cy.get("#search_patient_name").should("be.visible").type(patientName); - } - - verifyPatientName(patientName: string): void { - cy.verifyContentPresence("#sample-test-patient-name", [patientName]); - } - - clickOnSampleDetailsBtn(): void { - cy.get("#sample-details-btn").should("be.visible").first().click(); - } - - verifyPatientTestDetails( - patientName: string, - fastTrackReason: string, - doctorName: string, - diagnosis: string, - differentialDiagnosis: string, - etiologyIdentified: string, - ): void { - cy.verifyContentPresence("#patient_name", [patientName]); - cy.verifyContentPresence("#fast_track_reason", [fastTrackReason]); - cy.verifyContentPresence("#doctor_name", [doctorName]); - cy.verifyContentPresence("#diagnosis", [diagnosis]); - cy.verifyContentPresence("#diff_diagnosis", [differentialDiagnosis]); - cy.verifyContentPresence("#etiology_identified", [etiologyIdentified]); - } - - interceptSampleTestReq(): void { - cy.intercept("POST", "**/api/v1/patient/*/test_sample/").as( - "sampleDetails", - ); - } - - verifySampleTestReq(): void { - cy.wait("@sampleDetails").its("response.statusCode").should("eq", 201); - } - - interceptGetSampleTestReq(): void { - cy.intercept("GET", "**/api/v1/test_sample/**").as("getSampleTestReq"); - } - - verifyGetSampleTestReq(): void { - cy.wait("@getSampleTestReq").its("response.statusCode").should("eq", 200); - } -} diff --git a/public/External-Results-Template.csv b/public/External-Results-Template.csv deleted file mode 100644 index c2601f2d64f..00000000000 --- a/public/External-Results-Template.csv +++ /dev/null @@ -1,3 +0,0 @@ -District,SRF ID,Name,Age,Age in,Gender,Mobile Number,Address,Ward,Local Body,Local Body Type,Source,Sample Collection Date,Result Date,Test Type,Lab Name,Sample Type,Patient Status,Is Repeat,Patient Category,Result -Ernakulam,00/EKM/0000,Bodhi CSN,24,years,m,8888888888,"CSN HQ -Kochi, Kerala ",7,Poothrikka,grama panchayath,Secondary contact aparna,2020-10-14,2020-10-14,Antigen,Karothukuzhi Laboratory,Ag-SD_Biosensor_Standard_Q_COVID-19_Ag_detection_kit,Asymptomatic,NO,Cat 17: All individuals who wish to get themselves tested,Negative \ No newline at end of file diff --git a/public/locale/en.json b/public/locale/en.json index 4b262e61d10..b9418edd719 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -181,14 +181,6 @@ "ROUNDS_TYPE__NORMAL": "Brief Update", "ROUNDS_TYPE__TELEMEDICINE": "Tele-medicine Log", "ROUNDS_TYPE__VENTILATOR": "Detailed Update", - "SAMPLE_TEST_HISTORY__APPROVED": "Approved", - "SAMPLE_TEST_HISTORY__COMPLETED": "Completed", - "SAMPLE_TEST_HISTORY__RECEIVED_AT_LAB": "Received At Lab", - "SAMPLE_TEST_HISTORY__REQUEST_SUBMITTED": "Request Submitted", - "SAMPLE_TEST_RESULT__AWAITING": "Awaiting", - "SAMPLE_TEST_RESULT__INVALID": "Invalid", - "SAMPLE_TEST_RESULT__NEGATIVE": "Negative", - "SAMPLE_TEST_RESULT__POSITIVE": "Positive", "SLEEP__EXCESSIVE": "Excessive", "SLEEP__NO_SLEEP": "No sleep", "SLEEP__SATISFACTORY": "Satisfactory", @@ -354,7 +346,6 @@ "asset_type": "Asset Type", "assets": "Assets", "assign": "Assign", - "unassign":"Unassign", "assign_a_volunteer_to": "Assign a volunteer to {{name}}", "assign_bed": "Assign Bed", "assign_to_volunteer": "Assign to a Volunteer", @@ -1444,6 +1435,7 @@ "type_your_comment": "Type your comment", "type_your_reason_here": "Type your reason here", "unable_to_get_current_position": "Unable to get current position.", + "unassign": "Unassign", "unconfirmed": "Unconfirmed", "unique_id": "Unique Id", "unknown": "Unknown", @@ -1558,8 +1550,8 @@ "voice_autofill": "Voice Autofill", "volunteer_assigned": "Volunteer assigned successfully", "volunteer_contact": "Volunteer Contact", - "volunteer_update" : "Volunteer updated successfully", "volunteer_unassigned": "Volunteer unassigned successfully", + "volunteer_update": "Volunteer updated successfully", "ward": "Ward", "warranty_amc_expiry": "Warranty / AMC Expiry", "weekly_working_hours_error": "Average weekly working hours must be a number between 0 and 168", diff --git a/public/locale/hi.json b/public/locale/hi.json index b3c172021dd..9e6a667ba23 100644 --- a/public/locale/hi.json +++ b/public/locale/hi.json @@ -106,7 +106,6 @@ "SORT_OPTIONS__name": "मरीज़ का नाम AZ", "SORT_OPTIONS__review_time": "सबसे पुरानी समीक्षा तिथि पहले", "SORT_OPTIONS__taken_at": "सबसे पुरानी ली गई तारीख पहले", - "Sample Test": "नमूना परीक्षण", "Shifting": "स्थानांतरण", "Submit": "जमा करना", "TELEMEDICINE": "सुदूर", diff --git a/src/Routers/AppRouter.tsx b/src/Routers/AppRouter.tsx index 8ba9460e34b..e5b3d5b3eb1 100644 --- a/src/Routers/AppRouter.tsx +++ b/src/Routers/AppRouter.tsx @@ -24,7 +24,6 @@ import ConsultationRoutes from "@/Routers/routes/ConsultationRoutes"; import FacilityRoutes from "@/Routers/routes/FacilityRoutes"; import PatientRoutes from "@/Routers/routes/PatientRoutes"; import ResourceRoutes from "@/Routers/routes/ResourceRoutes"; -import SampleRoutes from "@/Routers/routes/SampleRoutes"; import ShiftingRoutes from "@/Routers/routes/ShiftingRoutes"; import UserRoutes from "@/Routers/routes/UserRoutes"; @@ -51,7 +50,6 @@ const Routes: AppRoutes = { ...FacilityRoutes, ...PatientRoutes, ...ResourceRoutes, - ...SampleRoutes, ...ShiftingRoutes, ...UserRoutes, diff --git a/src/Routers/routes/SampleRoutes.tsx b/src/Routers/routes/SampleRoutes.tsx deleted file mode 100644 index d9d3162cdd9..00000000000 --- a/src/Routers/routes/SampleRoutes.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { SampleDetails } from "@/components/Patient/SampleDetails"; -import SampleReport from "@/components/Patient/SamplePreview"; -import { SampleTest } from "@/components/Patient/SampleTest"; -import SampleViewAdmin from "@/components/Patient/SampleViewAdmin"; - -import { AppRoutes } from "@/Routers/AppRouter"; - -const SampleRoutes: AppRoutes = { - "/sample": () => , - "/sample/:id": ({ id }) => , - "/patient/:patientId/test_sample/:sampleId/icmr_sample": ({ - patientId, - sampleId, - }) => , - "/facility/:facilityId/patient/:patientId/sample-test": ({ - facilityId, - patientId, - }) => , - "/facility/:facilityId/patient/:patientId/sample/:id": ({ id }) => ( - - ), -}; - -export default SampleRoutes; diff --git a/src/Utils/request/api.tsx b/src/Utils/request/api.tsx index 40021007773..e7df6312c84 100644 --- a/src/Utils/request/api.tsx +++ b/src/Utils/request/api.tsx @@ -70,12 +70,7 @@ import { NotificationData, PNconfigData, } from "@/components/Notifications/models"; -import { - DailyRoundsModel, - PatientModel, - SampleReportModel, - SampleTestModel, -} from "@/components/Patient/models"; +import { DailyRoundsModel, PatientModel } from "@/components/Patient/models"; import { CreateFileRequest, CreateFileResponse, @@ -785,22 +780,6 @@ const routes = { method: "GET", TRes: Type>(), }, - sampleTestList: { - path: "/api/v1/patient/{patientId}/test_sample/", - method: "GET", - TRes: Type>(), - }, - createSampleTest: { - path: "/api/v1/patient/{patientId}/test_sample/", - method: "POST", - TRes: Type(), - TBody: Type(), - }, - sampleReport: { - path: "/api/v1/patient/{id}/test_sample/{sampleId}/icmr_sample/", - method: "GET", - TRes: Type(), - }, // States statesList: { @@ -869,24 +848,6 @@ const routes = { TRes: Type>(), }, - // Sample Test - getTestSampleList: { - path: "/api/v1/test_sample/", - method: "GET", - TRes: Type>(), - }, - getTestSample: { - path: "/api/v1/test_sample/{id}/", - method: "GET", - TRes: Type(), - }, - patchSample: { - path: "/api/v1/test_sample/{id}/", - method: "PATCH", - TBody: Type(), - TRes: Type(), - }, - //inventory getItems: { path: "/api/v1/items/", diff --git a/src/common/constants.tsx b/src/common/constants.tsx index 9d0be731565..ff215a0635a 100644 --- a/src/common/constants.tsx +++ b/src/common/constants.tsx @@ -363,13 +363,6 @@ export const GENDER_TYPES = [ { id: 3, text: "Transgender", icon: "TRANS" }, ] as const; -export const SAMPLE_TEST_RESULT = [ - { id: 1, text: "POSITIVE" }, - { id: 2, text: "NEGATIVE" }, - { id: 3, text: "AWAITING" }, - { id: 4, text: "INVALID" }, -]; - export const CONSULTATION_SUGGESTION = [ { id: "HI", text: "Home Isolation", deprecated: true }, // # Deprecated. Preserving option for backward compatibility (use only for readonly operations) { id: "A", text: "Admission" }, @@ -463,48 +456,6 @@ export const PATIENT_CATEGORIES: { export const PATIENT_FILTER_CATEGORIES = PATIENT_CATEGORIES; -export const SAMPLE_TEST_STATUS = [ - { id: 1, text: "REQUEST_SUBMITTED", desc: "Request Submitted" }, - { id: 2, text: "APPROVED", desc: "Approved for Sample Collection" }, - { id: 3, text: "DENIED", desc: "Request Denied" }, - { - id: 4, - text: "SENT_TO_COLLECTON_CENTRE", - desc: "Sample taken and sent to collection centre", - }, - { id: 5, text: "RECEIVED_AND_FORWARED", desc: "Received And Forwarded" }, - { id: 6, text: "RECEIVED_AT_LAB", desc: "Received At Lab" }, - { id: 7, text: "COMPLETED", desc: "Test Completed" }, -]; - -export const SAMPLE_FLOW_RULES = { - REQUEST_SUBMITTED: ["APPROVED", "DENIED"], - APPROVED: [ - "SENT_TO_COLLECTON_CENTRE", - "RECEIVED_AND_FORWARED", - "RECEIVED_AT_LAB", - "COMPLETED", - ], - DENIED: ["REQUEST_SUBMITTED"], - SENT_TO_COLLECTON_CENTRE: [ - "RECEIVED_AND_FORWARED", - "RECEIVED_AT_LAB", - "COMPLETED", - ], - RECEIVED_AND_FORWARED: ["RECEIVED_AT_LAB", "COMPLETED"], - RECEIVED_AT_LAB: ["COMPLETED"], -}; - -export const TEST_TYPE = [ - "UNK", - "ANTIGEN", - "RTPCR", - "CBNAAT", - "TRUENAT", - "RTLAMP", - "POCPCR", -]; - export const VACCINES = [ "CoviShield", "Covaxin", diff --git a/src/components/Common/Breadcrumbs.tsx b/src/components/Common/Breadcrumbs.tsx index 0435d7675d9..c2c4aa57446 100644 --- a/src/components/Common/Breadcrumbs.tsx +++ b/src/components/Common/Breadcrumbs.tsx @@ -13,7 +13,6 @@ const MENU_TAGS: { [key: string]: string } = { facility: "Facilities", patients: "Patients", assets: "Assets", - sample: "Sample Tests", shifting: "Shiftings", resource: "Resources", users: "Users", diff --git a/src/components/Common/Sidebar/Sidebar.tsx b/src/components/Common/Sidebar/Sidebar.tsx index ed0a1a4eee5..423d0d6f18b 100644 --- a/src/components/Common/Sidebar/Sidebar.tsx +++ b/src/components/Common/Sidebar/Sidebar.tsx @@ -59,7 +59,6 @@ const StatelessSidebar = ({ { text: t("facilities"), to: "/facility", icon: "d-hospital" }, { text: t("patients"), to: "/patients", icon: "d-patient" }, { text: t("assets"), to: "/assets", icon: "d-folder" }, - { text: t("sample_test"), to: "/sample", icon: "d-microscope" }, { text: t("shifting"), to: "/shifting", icon: "d-ambulance" }, { text: t("resource"), to: "/resource", icon: "d-book-open" }, { text: t("users"), to: "/users", icon: "d-people" }, diff --git a/src/components/Patient/PatientDetailsTab/SampleTestHistory.tsx b/src/components/Patient/PatientDetailsTab/SampleTestHistory.tsx deleted file mode 100644 index b7a907fe662..00000000000 --- a/src/components/Patient/PatientDetailsTab/SampleTestHistory.tsx +++ /dev/null @@ -1,107 +0,0 @@ -import { navigate } from "raviger"; -import React, { useState } from "react"; -import { useTranslation } from "react-i18next"; - -import CareIcon from "@/CAREUI/icons/CareIcon"; -import PaginatedList from "@/CAREUI/misc/PaginatedList"; - -import ButtonV2 from "@/components/Common/ButtonV2"; -import CircularProgress from "@/components/Common/CircularProgress"; - -import { NonReadOnlyUsers } from "@/Utils/AuthorizeFor"; -import routes from "@/Utils/request/api"; - -import { PatientProps } from "."; -import { SampleTestCard } from "../SampleTestCard"; -import { PatientModel, SampleTestModel } from "../models"; - -export const SampleTestHistory = (props: PatientProps) => { - const { patientData, facilityId, id } = props; - const [_selectedStatus, setSelectedStatus] = useState<{ - status: number; - sample: SampleTestModel | null; - }>({ status: 0, sample: null }); - const [_showAlertMessage, setShowAlertMessage] = useState(false); - - const isPatientInactive = (patientData: PatientModel, facilityId: string) => { - if (!patientData) return true; - return ( - !patientData.is_active || - !( - patientData?.last_consultation && - patientData.last_consultation.facility === facilityId - ) - ); - }; - - const confirmApproval = (status: number, sample: SampleTestModel) => { - setSelectedStatus({ status, sample }); - setShowAlertMessage(true); - }; - - const { t } = useTranslation(); - - return ( -
-
-
-

- {t("sample_test_history")} -

- - navigate( - `/facility/${patientData?.facility}/patient/${id}/sample-test`, - ) - } - authorizeFor={NonReadOnlyUsers} - id="sample-request-btn" - > - - - {t("request_sample_test")} - - -
-
- - - {(_, query) => ( -
- - - - -
-
- {t("no_records_found")} -
-
-
- > - {(item) => ( - - )} - -
- -
-
- )} -
-
- ); -}; diff --git a/src/components/Patient/PatientDetailsTab/index.tsx b/src/components/Patient/PatientDetailsTab/index.tsx index effc9b667f8..6f4b7ecc982 100644 --- a/src/components/Patient/PatientDetailsTab/index.tsx +++ b/src/components/Patient/PatientDetailsTab/index.tsx @@ -4,7 +4,6 @@ import EncounterHistory from "./EncounterHistory"; import { HealthProfileSummary } from "./HealthProfileSummary"; import { ImmunisationRecords } from "./ImmunisationRecords"; import PatientNotes from "./Notes"; -import { SampleTestHistory } from "./SampleTestHistory"; import ShiftingHistory from "./ShiftingHistory"; export interface PatientProps { @@ -34,10 +33,6 @@ export const patientTabs = [ route: "shift", component: ShiftingHistory, }, - { - route: "request-sample-test", - component: SampleTestHistory, - }, { route: "patient-notes", component: PatientNotes, diff --git a/src/components/Patient/PatientHome.tsx b/src/components/Patient/PatientHome.tsx index 7ae439fa80b..253bd823ac0 100644 --- a/src/components/Patient/PatientHome.tsx +++ b/src/components/Patient/PatientHome.tsx @@ -11,7 +11,6 @@ import { DISCHARGE_REASONS, GENDER_TYPES, OCCUPATION_TYPES, - SAMPLE_TEST_STATUS, } from "@/common/constants"; import dayjs from "@/Utils/dayjs"; @@ -40,7 +39,7 @@ import Page from "../Common/Page"; import { SkillModel, UserBareMinimum } from "../Users/models"; import { patientTabs } from "./PatientDetailsTab"; import { isPatientMandatoryDataFilled } from "./Utils"; -import { AssignedToObjectModel, PatientModel, SampleTestModel } from "./models"; +import { AssignedToObjectModel, PatientModel } from "./models"; export const parseOccupation = (occupation: string | undefined) => { return OCCUPATION_TYPES.find((i) => i.value === occupation)?.text; @@ -56,10 +55,6 @@ export const PatientHome = (props: { const authUser = useAuthUser(); const { t } = useTranslation(); - const [selectedStatus, _setSelectedStatus] = useState<{ - status: number; - sample: SampleTestModel | null; - }>({ status: 0, sample: null }); const [assignedVolunteer, setAssignedVolunteer] = useState< AssignedToObjectModel | undefined @@ -69,7 +64,6 @@ export const PatientHome = (props: { setAssignedVolunteer(patientData.assigned_to_object); }, [patientData.assigned_to_object]); - const [showAlertMessage, setShowAlertMessage] = useState(false); const [openAssignVolunteerDialog, setOpenAssignVolunteerDialog] = useState(false); @@ -152,31 +146,6 @@ export const PatientHome = (props: { return `${first}, ${second} and ${rest.length} other skills...`; }; - const handleApproval = async () => { - const { status, sample } = selectedStatus; - const sampleData = { - id: sample?.id, - status: status.toString(), - consultation: sample?.consultation, - }; - const statusName = SAMPLE_TEST_STATUS.find((i) => i.id === status)?.desc; - - await request(routes.patchSample, { - body: sampleData, - pathParams: { - id: sample?.id || "", - }, - onResponse: ({ res }) => { - if (res?.ok) { - Notification.Success({ - msg: `Request ${statusName}`, - }); - } - setShowAlertMessage(false); - }, - }); - }; - if (isLoading) { return ; } @@ -216,15 +185,6 @@ export const PatientHome = (props: { }} backUrl={facilityId ? `/facility/${facilityId}/patients` : "/patients"} > - handleApproval()} - onClose={() => setShowAlertMessage(false)} - /> -
diff --git a/src/components/Patient/SampleDetails.tsx b/src/components/Patient/SampleDetails.tsx deleted file mode 100644 index f0e5f0039e5..00000000000 --- a/src/components/Patient/SampleDetails.tsx +++ /dev/null @@ -1,558 +0,0 @@ -import { Link, navigate } from "raviger"; -import { useTranslation } from "react-i18next"; - -import { Badge } from "@/components/ui/badge"; -import { Button } from "@/components/ui/button"; -import { Card, CardContent, CardHeader } from "@/components/ui/card"; - -import Loading from "@/components/Common/Loading"; -import Page from "@/components/Common/Page"; -import { FileUpload } from "@/components/Files/FileUpload"; -import { FlowModel } from "@/components/Patient/models"; - -import { GENDER_TYPES, TEST_TYPE_CHOICES } from "@/common/constants"; - -import { DetailRoute } from "@/Routers/types"; -import routes from "@/Utils/request/api"; -import useTanStackQueryInstead from "@/Utils/request/useQuery"; -import { formatDateTime, formatPatientAge } from "@/Utils/utils"; - -export const SampleDetails = ({ id }: DetailRoute) => { - const { t } = useTranslation(); - const { loading: isLoading, data: sampleDetails } = useTanStackQueryInstead( - routes.getTestSample, - { - pathParams: { - id, - }, - onResponse: ({ res, data }) => { - if (!(res?.ok && data)) { - navigate("/not-found"); - } - }, - }, - ); - - const yesOrNoBadge = (param: any) => - param ? ( - {t("yes")} - ) : ( - {t("no")} - ); - - const showPatientCard = (patientData: any) => { - const patientGender = GENDER_TYPES.find( - (i) => i.id === patientData?.gender, - )?.text; - const testType = TEST_TYPE_CHOICES.find( - (i) => i.id === patientData?.test_type, - )?.text; - - return ( -
-
-
-
- - {t("name")}:{" "} - - {patientData?.name} -
- {patientData?.is_medical_worker && ( -
- - {t("medical_worker")}:{" "} - - - {t("yes")} - -
- )} -
- - {t("disease_status")}:{" "} - - - {patientData?.disease_status} - -
- -
- - {t("srf_id")}:{" "} - - {(patientData?.srf_id && patientData?.srf_id) || "-"} -
-
- - {t("test_type")}:{" "} - - {(patientData?.test_type && testType) || "-"} -
-
- - {t("date_of_test")}:{" "} - - {(patientData?.date_of_test && - formatDateTime(patientData?.date_of_test)) || - "-"} -
- -
- - {t("facility")}:{" "} - - {patientData?.facility_object?.name || "-"} -
- {patientData?.date_of_birth ? ( -
- - {t("date_of_birth")}:{" "} - - {patientData?.date_of_birth} -
- ) : ( -
- - {t("age")}:{" "} - - {formatPatientAge(patientData)} -
- )} -
- - {t("gender")}:{" "} - - {patientGender} -
-
- - {t("phone")}:{" "} - - - {patientData?.phone_number || "-"} - -
-
- - {t("nationality")}:{" "} - - {patientData?.nationality || "-"} -
-
-
-
- - {t("blood_group")}:{" "} - - {patientData?.blood_group || "-"} -
- {patientData?.nationality !== "India" && ( -
- - {t("passport_number")}:{" "} - - {patientData?.passport_no || "-"} -
- )} - {patientData?.nationality === "India" && ( - <> -
- - {t("state")}:{" "} - - {patientData?.state_object?.name} -
-
- - {t("district")}:{" "} - - {patientData?.district_object?.name || "-"} -
-
- - {t("local_body")}:{" "} - - {patientData?.local_body_object?.name || "-"} -
- - )} -
- - {t("address")}:{" "} - - {patientData?.address || "-"} -
-
- - {t("contact_with_confirmed_carrier")}:{" "} - - {yesOrNoBadge(patientData?.contact_with_confirmed_carrier)} -
-
- - {t("contact_with_suspected_carrier")}:{" "} - - {yesOrNoBadge(patientData?.contact_with_suspected_carrier)} -
- {patientData?.estimated_contact_date && ( -
- - {t("estimated_contact_date")}:{" "} - - {formatDateTime(patientData?.estimated_contact_date)} -
- )} -
- - {t("has_sari")}:{" "} - - {yesOrNoBadge(patientData?.has_SARI)} -
-
- - {t("domestic_international_travel")}:{" "} - - {yesOrNoBadge(patientData?.past_travel)} -
- {patientData?.countries_travelled && - !!patientData?.countries_travelled.length && ( -
- - {t("countries_travelled")}:{" "} - - {patientData?.countries_travelled.join(", ")} -
- )} - {patientData?.ongoing_medication && ( -
- - {t("ongoing_medications")}{" "} - - {patientData?.ongoing_medication} -
- )} - {patientData?.allergies && ( -
- - {t("allergies")}:{" "} - - {patientData?.allergies} -
- )} - {!!patientData?.number_of_aged_dependents && ( -
- - {t("number_of_aged_dependents")}:{" "} - - {patientData?.number_of_aged_dependents} -
- )} - {!!patientData?.number_of_chronic_diseased_dependents && ( -
- - {t("number_of_chronic_diseased_dependents")}:{" "} - - {patientData?.number_of_chronic_diseased_dependents} -
- )} -
-
-
- ); - }; - - const renderFlow = (flow: FlowModel) => { - return ( - -
-
- - {t("status")}:{" "} - {" "} - {t(`SAMPLE_TEST_HISTORY__${flow.status}`) || "Unknown"} -
-
- {t("label")}:{" "} - {flow.notes} -
-
- - {t("created_on")}: - {" "} - {flow.created_date ? formatDateTime(flow.created_date) : "-"} -
-
- - {t("modified_on")}: - {" "} - {flow.modified_date ? formatDateTime(flow.modified_date) : "-"} -
-
-
- ); - }; - - if (isLoading || !sampleDetails) { - return ; - } - - return ( - - -
- ) - } - > - - -
-
-
- {t("status")}:{" "} -
- - {t(`SAMPLE_TEST_HISTORY__${sampleDetails?.status}`)} - -
-
-
- {t("result")}:{" "} -
- - {t(`SAMPLE_TEST_RESULT__${sampleDetails?.result}`)} - -
-
-
- -
-
-
- {t("patient")}: -
-
- {sampleDetails?.patient_name || "-"} -
-
- {sampleDetails?.facility_object && ( -
-
- {t("facility")}:{" "} -
-
- {sampleDetails?.facility_object.name} -
-
- )} -
-
- {t("tested_on")}:{" "} -
-
- {sampleDetails?.date_of_result - ? formatDateTime(sampleDetails.date_of_result) - : "-"} -
-
-
-
- {t("result_on")}:{" "} -
-
- {sampleDetails?.date_of_result - ? formatDateTime(sampleDetails.date_of_result) - : "-"} -
-
-
- - {sampleDetails?.doctor_name && ( -
-
- {t("doctors_name")}: -
-
- {sampleDetails.doctor_name} -
-
- )} -
-
- {sampleDetails?.fast_track && ( -
-
- {t("fast_track_testing_reason")}:{" "} -
- {sampleDetails.fast_track} -
- )} - {sampleDetails?.diagnosis && ( -
-
{t("diagnosis")}:
- - {" "} - {sampleDetails.diagnosis} - -
- )} - {sampleDetails?.diff_diagnosis && ( -
-
- {t("differential_diagnosis")}:{" "} -
- - {" "} - {sampleDetails?.diff_diagnosis} - -
- )} - {sampleDetails?.etiology_identified && ( -
-
- {t("etiology_identified")}:{" "} -
- - {" "} - {sampleDetails.etiology_identified} - -
- )} -
-
- {t("is_atypical_presentation")} -
- - {" "} - {yesOrNoBadge(sampleDetails?.is_atypical_presentation)} - -
-
-
- {t("is_unusual_course")} -
- - {" "} - {yesOrNoBadge(sampleDetails?.is_unusual_course)} - -
- {sampleDetails?.atypical_presentation && ( -
-
- {t("atypical_presentation_details")}:{" "} -
- - {" "} - {sampleDetails.atypical_presentation} - -
- )} -
-
{t("sari")}
- - {" "} - {yesOrNoBadge(sampleDetails?.has_sari)} - -
-
-
{t("ari")}
- - {" "} - {yesOrNoBadge(sampleDetails?.has_ari)} - -
-
-
- {t("contact_with_confirmed_carrier")}{" "} -
- - {" "} - {yesOrNoBadge(sampleDetails?.patient_has_confirmed_contact)} - -
-
-
- {t("contact_with_suspected_carrier")}{" "} -
- - {" "} - {yesOrNoBadge(sampleDetails?.patient_has_suspected_contact)} - -
- {sampleDetails?.patient_travel_history && - sampleDetails.patient_travel_history.length !== 0 && ( -
-
- {t("countries_travelled")}:{" "} -
- - {" "} - {sampleDetails.patient_travel_history} - -
- )} -
-
- {sampleDetails?.sample_type && ( -
-
- {t("sample_type")}:{" "} -
- - {sampleDetails.sample_type} - -
- )} - {sampleDetails?.sample_type === "OTHER TYPE" && ( -
-
- {t("sample_type_description")}:{" "} -
-
- {sampleDetails?.sample_type_other} -
-
- )} -
-
- -
-

{t("details_of_patient")}

- {showPatientCard(sampleDetails?.patient_object)} -
- -
-

{t("sample_test_history")}

- {sampleDetails?.flow && - sampleDetails.flow.map((flow: FlowModel) => ( -
- {renderFlow(flow)} -
- ))} -
- - - - ); -}; diff --git a/src/components/Patient/SampleFilters.tsx b/src/components/Patient/SampleFilters.tsx deleted file mode 100644 index 6ac3a4532b7..00000000000 --- a/src/components/Patient/SampleFilters.tsx +++ /dev/null @@ -1,131 +0,0 @@ -import FiltersSlideover from "@/CAREUI/interactive/FiltersSlideover"; - -import CircularProgress from "@/components/Common/CircularProgress"; -import { FacilitySelect } from "@/components/Common/FacilitySelect"; -import { FacilityModel } from "@/components/Facility/models"; -import { FieldLabel } from "@/components/Form/FormFields/FormField"; -import { SelectFormField } from "@/components/Form/FormFields/SelectFormField"; -import { FieldChangeEvent } from "@/components/Form/FormFields/Utils"; - -import useMergeState from "@/hooks/useMergeState"; - -import { - SAMPLE_TEST_RESULT, - SAMPLE_TEST_STATUS, - SAMPLE_TYPE_CHOICES, -} from "@/common/constants"; - -import routes from "@/Utils/request/api"; -import useTanStackQueryInstead from "@/Utils/request/useQuery"; - -export default function UserFilter(props: any) { - const { filter, onChange, closeFilter, removeFilters } = props; - - const [filterState, setFilterState] = useMergeState({ - status: filter.status || "", - result: filter.result || "", - facility: filter.facility || "", - facility_ref: filter.facility_ref || null, - sample_type: filter.sample_type || "", - }); - - const handleChange = ({ name, value }: FieldChangeEvent) => { - setFilterState({ ...filterState, [name]: value }); - }; - - const applyFilter = () => { - const { status, result, facility, sample_type } = filterState; - const data = { - status: status || "", - result: result || "", - facility: facility || "", - sample_type: sample_type || "", - }; - onChange(data); - }; - - const { loading: isFacilityLoading } = useTanStackQueryInstead( - routes.getAnyFacility, - { - pathParams: { - id: filter.facility, - }, - prefetch: !!filter.facility, - onResponse: ({ data }) => { - setFilterState({ ...filterState, facility_ref: data }); - }, - }, - ); - - return ( - { - removeFilters(); - closeFilter(); - }} - > - { - return { id, text: text.replaceAll("_", " ") }; - })} - optionValue={(option) => option.id} - optionLabel={(option) => option.text} - labelClassName="text-sm" - errorClassName="hidden" - /> - - option.id} - optionLabel={(option) => option.text} - labelClassName="text-sm" - errorClassName="hidden" - /> - - option.id} - optionLabel={(option) => option.text} - labelClassName="text-sm" - errorClassName="hidden" - /> - -
- Facility -
- {isFacilityLoading ? ( - - ) : ( - - setFilterState({ - facility: (obj as FacilityModel)?.id, - facility_ref: obj, - }) - } - errors={""} - /> - )} -
-
-
- ); -} diff --git a/src/components/Patient/SamplePreview.tsx b/src/components/Patient/SamplePreview.tsx deleted file mode 100644 index 18862712533..00000000000 --- a/src/components/Patient/SamplePreview.tsx +++ /dev/null @@ -1,459 +0,0 @@ -import ButtonV2 from "@/components/Common/ButtonV2"; -import Loading from "@/components/Common/Loading"; -import Page from "@/components/Common/Page"; - -import routes from "@/Utils/request/api"; -import useTanStackQueryInstead from "@/Utils/request/useQuery"; -import { classNames, formatDateTime, humanizeStrings } from "@/Utils/utils"; - -interface ISamplePreviewProps { - id: string; - sampleId: string; -} - -interface ISampleReportSectionProps { - title: string; - fields: { - title: string; - value: string | undefined | null; - }[]; -} - -function SampleReportSection({ title, fields }: ISampleReportSectionProps) { - return ( - <> -
-
{title}
-
-
- {fields.map((field, i) => ( -
-
-

- {field.title} -

-
-
-

- {field.value} -

-
-
- ))} -
- - ); -} - -export default function SampleReport(props: ISamplePreviewProps) { - const { id, sampleId } = props; - - let report: JSX.Element = <>; - let reportData: JSX.Element = <>; - - const { loading: isLoading, data: sampleData } = useTanStackQueryInstead( - routes.sampleReport, - { - pathParams: { - id, - sampleId, - }, - }, - ); - - if (sampleData) { - reportData = ( - <> -
- - Print Report - -
-
-
-
-
-
-
- Open HealthCare Network -
-
-
-
-
-

- ICMR Specimen Referral Data for COVID-19 (SARS-CoV2) -

-
-
-
-
- FOR INTERNAL USE ONLY -
-
-
-
-
Sample Id : {sampleId}
-
-
-
Patient Id : {id}
-
-
-
-
SECTION A - MANDATORY FIELDS
-
- - - - - { - switch (sampleData?.specimen_details?.icmr_category) { - case "Cat 0": - return "Repeat Sample of Positive Case / Follow Up case"; - case "Cat 1": - return "Symptomatic International Traveller in last 14 days"; - case "Cat 2": - return "Symptomatic contact of lab confirmed Case"; - case "Cat 3": - return "Symptomatic Healthcare Worker"; - case "Cat 4": - return "Hospitalized SARI (Severe Acute Respiratory illness Patient)"; - case "Cat 5a": - return "Asymptomatic Direct and High Risk contact of confirmed case - family Member"; - case "Cat 5b": - return "Asymptomatic Healthcare worker in contact with confimred case without adequete protection"; - } - })(), - }, - ]} - /> - -
-
- SECTION B - OTHER FIELDS TO BE UPDATED -
-
- - - - - - - - - - -
-
-
-
- - ); - } - if (isLoading) { - report = ( -
- -
- ); - } else if (sampleData && reportData) { - report = reportData; - } else if (!sampleData) { - report = ( -
-
No Data Found
-
- ); - } - return ( -
- - {report} - -
- ); -} diff --git a/src/components/Patient/SampleTest.tsx b/src/components/Patient/SampleTest.tsx deleted file mode 100644 index 7025faf407e..00000000000 --- a/src/components/Patient/SampleTest.tsx +++ /dev/null @@ -1,350 +0,0 @@ -import { navigate } from "raviger"; -import { useReducer, useState } from "react"; - -import { Cancel, Submit } from "@/components/Common/ButtonV2"; -import { FacilitySelect } from "@/components/Common/FacilitySelect"; -import Loading from "@/components/Common/Loading"; -import Page from "@/components/Common/Page"; -import CheckBoxFormField from "@/components/Form/FormFields/CheckBoxFormField"; -import { FieldLabel } from "@/components/Form/FormFields/FormField"; -import { SelectFormField } from "@/components/Form/FormFields/SelectFormField"; -import TextAreaFormField from "@/components/Form/FormFields/TextAreaFormField"; -import TextFormField from "@/components/Form/FormFields/TextFormField"; -import { FieldChangeEvent } from "@/components/Form/FormFields/Utils"; -import { SampleTestModel } from "@/components/Patient/models"; - -import useAppHistory from "@/hooks/useAppHistory"; - -import { ICMR_CATEGORY, SAMPLE_TYPE_CHOICES } from "@/common/constants"; - -import * as Notification from "@/Utils/Notifications"; -import routes from "@/Utils/request/api"; -import request from "@/Utils/request/request"; -import useTanStackQueryInstead from "@/Utils/request/useQuery"; - -const initForm: SampleTestModel = { - isFastTrack: false, - fast_track: "", - icmr_label: "", - atypical_presentation: "", - diagnosis: "", - diff_diagnosis: "", - doctor_name: "", - testing_facility: "", - etiology_identified: "", - has_ari: false, - has_sari: false, - is_atypical_presentation: false, - is_unusual_course: false, - sample_type: "0", - icmr_category: "Cat 0", - sample_type_other: "", -}; - -const initError = Object.assign( - {}, - ...Object.keys(initForm).map((k) => ({ [k]: "" })), -); - -const initialState = { - form: { ...initForm }, - errors: { ...initError }, -}; - -const sampleTestFormReducer = (state = initialState, action: any) => { - switch (action.type) { - case "set_form": { - return { - ...state, - form: action.form, - }; - } - case "set_error": { - return { - ...state, - errors: action.errors, - }; - } - default: - return state; - } -}; - -export const SampleTest = ({ facilityId, patientId }: any) => { - const { goBack } = useAppHistory(); - const [state, dispatch] = useReducer(sampleTestFormReducer, initialState); - const [isLoading, setIsLoading] = useState(false); - - const headerText = "Request Sample"; - const buttonText = "Confirm your request to send sample for testing"; - - const { data } = useTanStackQueryInstead(routes.getPatient, { - pathParams: { - id: patientId, - }, - prefetch: !!patientId, - }); - - const validateForm = () => { - const errors = { ...initError }; - let invalidForm = false; - Object.keys(state.form).forEach((field) => { - switch (field) { - case "fast_track": - if (state.form.isFastTrack && !state.form[field]) { - errors[field] = "Please provide reasons for fast-track testing"; - invalidForm = true; - } - break; - case "icmr_label": - if (!state.form[field]) { - errors[field] = "Please specify the label"; - invalidForm = true; - } - break; - case "sample_type_other": - if (state.form.sample_type === "9" && !state.form[field]) { - errors[field] = "Please provide details of the sample type"; - invalidForm = true; - } - break; - case "atypical_presentation": - if (state.form.is_atypical_presentation && !state.form[field]) { - errors[field] = "Please provide details of atypical presentation"; - invalidForm = true; - } - break; - default: - return; - } - }); - if (invalidForm) { - dispatch({ type: "set_error", errors }); - return false; - } - dispatch({ type: "set_error", errors }); - return true; - }; - - const handleSubmit = async (e: any) => { - e.preventDefault(); - const validForm = validateForm(); - if (validForm) { - setIsLoading(true); - const data: SampleTestModel = { - date_of_sample: new Date().toISOString(), - fast_track: state.form.isFastTrack ? state.form.fast_track : undefined, - icmr_label: state.form.icmr_label ? state.form.icmr_label : undefined, - facility: facilityId, - patient: patientId, - has_ari: state.form.has_ari, - has_sari: state.form.has_sari, - is_unusual_course: state.form.is_unusual_course, - is_atypical_presentation: state.form.is_atypical_presentation, - atypical_presentation: state.form.is_atypical_presentation - ? state.form.atypical_presentation - : undefined, - diagnosis: state.form.diagnosis ? state.form.diagnosis : undefined, - diff_diagnosis: state.form.diff_diagnosis - ? state.form.diff_diagnosis - : undefined, - testing_facility: state.form.testing_facility?.id, - doctor_name: state.form.doctor_name - ? state.form.doctor_name - : undefined, - etiology_identified: state.form.etiology_identified - ? state.form.etiology_identified - : undefined, - sample_type: state.form.sample_type, - icmr_category: state.form.icmr_category, - sample_type_other: - state.form.sample_type === "9" - ? state.form.sample_type_other - : undefined, - }; - - await request(routes.createSampleTest, { - pathParams: { - patientId, - }, - body: data, - onResponse: ({ res, data }) => { - setIsLoading(false); - if (res?.ok && data) { - dispatch({ type: "set_form", form: initForm }); - Notification.Success({ - msg: "Sample test created successfully", - }); - navigate(`/facility/${facilityId}/patient/${patientId}`); - } - }, - }); - } - }; - - const handleFormFieldChange = (e: FieldChangeEvent) => { - dispatch({ type: "set_form", form: { ...state.form, [e.name]: e.value } }); - }; - - const field = (name: string, label: string) => ({ - name, - label, - value: state.form[name], - onChange: handleFormFieldChange, - error: state.errors[name], - }); - - if (isLoading) { - return ; - } - return ( - - - option.text} - optionValue={(option) => option.id} - id="sample-type" - /> - - {state.form.sample_type === "9" && ( - - )} - - option} - optionValue={(option) => option} - id="icmr-category" - /> -
-

- Refer below to know more about ICMR Categories -

- -
  • Cat 0 - Repeat Sample of Positive Case / Follow Up case
  • -
  • Cat 1 - Symptomatic International Traveller in last 14 days
  • -
  • Cat 2 - Symptomatic contact of lab confirmed Case
  • -
  • Cat 3 - Symptomatic Healthcare Worker
  • -
  • - Cat 4 - Hospitalized SARI (Severe Acute Respiratory illness - Patient) -
  • -
  • - Cat 5a - Asymptomatic Direct and High Risk contact of confirmed - case - family Member -
  • -
  • - Cat 5b - Asymptomatic Healthcare worker in contact with confirmed - case without adequate protection -
  • -
    -
    - - -
    - Testing Facility - - dispatch({ - type: "set_form", - form: { ...state.form, testing_facility: selected }, - }) - } - facilityType={950} - selected={state.form.testing_facility} - errors={state.errors.testing_facility} - showAll - multiple={false} - /> -
    - - {state.form.isFastTrack && ( - - )} - - - - {state.form.is_atypical_presentation && ( -
    - -
    - )} - - - - - - - -
    - goBack()} /> - -
    - -
    - ); -}; diff --git a/src/components/Patient/SampleTestCard.tsx b/src/components/Patient/SampleTestCard.tsx deleted file mode 100644 index f1d59980c23..00000000000 --- a/src/components/Patient/SampleTestCard.tsx +++ /dev/null @@ -1,227 +0,0 @@ -import { navigate } from "raviger"; -import { useState } from "react"; -import { useTranslation } from "react-i18next"; - -import ButtonV2 from "@/components/Common/ButtonV2"; -import RelativeDateUserMention from "@/components/Common/RelativeDateUserMention"; -import UpdateStatusDialog from "@/components/Patient/UpdateStatusDialog"; -import { SampleTestModel } from "@/components/Patient/models"; - -import { SAMPLE_TEST_STATUS } from "@/common/constants"; - -import { NonReadOnlyUsers } from "@/Utils/AuthorizeFor"; -import * as Notification from "@/Utils/Notifications"; -import routes from "@/Utils/request/api"; -import request from "@/Utils/request/request"; -import { formatDateTime } from "@/Utils/utils"; - -interface SampleDetailsProps { - facilityId: string; - patientId: string; - itemData: SampleTestModel; - refetch: () => void; - handleApproval: (status: number, sample: SampleTestModel) => void; -} - -export const SampleTestCard = (props: SampleDetailsProps) => { - const { t } = useTranslation(); - const { itemData, handleApproval, facilityId, patientId, refetch } = props; - - const [statusDialog, setStatusDialog] = useState<{ - show: boolean; - sample: SampleTestModel; - }>({ show: false, sample: {} }); - - const handleApproval1 = async ( - sample: SampleTestModel, - status: number, - result: number, - ) => { - const sampleData: any = { - id: sample.id, - status, - consultation: sample.consultation, - }; - if (status === 7) { - sampleData.result = result; - sampleData.date_of_result = new Date().toISOString(); - } - const statusName = SAMPLE_TEST_STATUS.find((i) => i.id === status)?.desc; - await request(routes.patchSample, { - pathParams: { - id: sample.id!, - }, - body: sampleData, - onResponse: ({ res }) => { - if (res?.ok) { - refetch(); - Notification.Success({ - msg: `Success - ${statusName}`, - }); - } - dismissUpdateStatus(); - }, - }); - }; - - const showUpdateStatus = (sample: SampleTestModel) => { - setStatusDialog({ - show: true, - sample, - }); - }; - - const dismissUpdateStatus = () => { - setStatusDialog({ - show: false, - sample: {}, - }); - }; - - return ( -
    -
    - navigate( - `/facility/${facilityId}/patient/${patientId}/sample/${itemData.id}`, - ) - } - className="ml-2 mt-2 grid grid-cols-1 gap-4 md:grid-cols-4" - > -
    -
    -
    - Status{" "} -
    -
    - {t(`SAMPLE_TEST_HISTORY__${itemData.status}`) || "Unknown"} -
    -
    -
    -
    -
    -
    - Sample Type{" "} -
    -
    - {itemData.sample_type?.toLowerCase()} -
    -
    -
    - {itemData.fast_track && ( -
    -
    -
    - Fast-Track{" "} -
    -
    - {itemData.fast_track} -
    -
    -
    - )} -
    -
    -
    - Result{" "} -
    -
    - {t(`SAMPLE_TEST_RESULT__${itemData.result}`) || "Unknown"} -
    -
    -
    -
    -
    -
    -
    -
    - Date of Sample:{" "} - {itemData.date_of_sample - ? formatDateTime(itemData.date_of_sample) - : "Not Available"} -
    -
    - Date of Result:{" "} - {itemData.date_of_result - ? formatDateTime(itemData.date_of_result) - : "Not Available"} -
    -
    -
    -
    -
    -
    Created:
    - - -
    -
    -
    Last Modified:
    - -
    -
    -
    -
    - {itemData.status === "APPROVED" && ( - { - e.stopPropagation(); - handleApproval(4, itemData); - }} - className="border border-secondary-500 bg-white text-black hover:bg-secondary-300" - > - Send to Collection Centre - - )} - showUpdateStatus(itemData)} - className="border border-secondary-500 bg-white text-black hover:bg-secondary-300" - authorizeFor={NonReadOnlyUsers} - > - Update Sample Test Status - - navigate(`/sample/${itemData.id}`)} - className="border border-secondary-500 bg-white text-black hover:bg-secondary-300" - > - Sample Report - -
    - {statusDialog.show && ( - - )} -
    - ); -}; diff --git a/src/components/Patient/SampleViewAdmin.tsx b/src/components/Patient/SampleViewAdmin.tsx deleted file mode 100644 index cf86b582dd8..00000000000 --- a/src/components/Patient/SampleViewAdmin.tsx +++ /dev/null @@ -1,423 +0,0 @@ -import { navigate } from "raviger"; -import { useState } from "react"; - -import CountBlock from "@/CAREUI/display/Count"; -import CareIcon from "@/CAREUI/icons/CareIcon"; -import { AdvancedFilterButton } from "@/CAREUI/interactive/FiltersSlideover"; - -import { ExportButton } from "@/components/Common/Export"; -import Loading from "@/components/Common/Loading"; -import Page from "@/components/Common/Page"; -import SearchInput from "@/components/Form/SearchInput"; -import SampleFilter from "@/components/Patient/SampleFilters"; -import UpdateStatusDialog from "@/components/Patient/UpdateStatusDialog"; -import { SampleTestModel } from "@/components/Patient/models"; - -import useFilters from "@/hooks/useFilters"; - -import { - SAMPLE_FLOW_RULES, - SAMPLE_TEST_RESULT, - SAMPLE_TEST_STATUS, - SAMPLE_TYPE_CHOICES, -} from "@/common/constants"; - -import * as Notification from "@/Utils/Notifications"; -import routes from "@/Utils/request/api"; -import request from "@/Utils/request/request"; -import useTanStackQueryInstead from "@/Utils/request/useQuery"; -import { formatDateTime } from "@/Utils/utils"; - -export default function SampleViewAdmin() { - const { - qParams, - updateQuery, - Pagination, - FilterBadges, - advancedFilter, - resultsPerPage, - } = useFilters({ - limit: 10, - cacheBlacklist: ["patient_name", "district_name"], - }); - let manageSamples: any = null; - const [statusDialog, setStatusDialog] = useState<{ - show: boolean; - sample: SampleTestModel; - }>({ show: false, sample: {} }); - - const { data: facilityData } = useTanStackQueryInstead( - routes.getAnyFacility, - { - pathParams: { - id: qParams.facility, - }, - prefetch: !!qParams.facility, - }, - ); - - const { - loading: isLoading, - data: sampeleData, - refetch, - } = useTanStackQueryInstead(routes.getTestSampleList, { - query: { - limit: resultsPerPage, - offset: (qParams.page ? qParams.page - 1 : 0) * resultsPerPage, - patient_name: qParams.patient_name || undefined, - district_name: qParams.district_name || undefined, - status: qParams.status || undefined, - result: qParams.result || undefined, - facility: qParams.facility || undefined, - sample_type: qParams.sample_type || undefined, - }, - }); - - const handleApproval = async ( - sample: SampleTestModel, - status: number, - result: number, - ) => { - const sampleData: any = { - id: sample.id, - status, - consultation: sample.consultation, - }; - if (status === 7) { - sampleData.result = result; - sampleData.date_of_result = new Date().toISOString(); - } - const statusName = SAMPLE_TEST_STATUS.find((i) => i.id === status)?.desc; - - await request(routes.patchSample, { - pathParams: { - id: sample.id || 0, - }, - body: sampleData, - onResponse: ({ res }) => { - if (res?.ok) { - Notification.Success({ - msg: `Success - ${statusName}`, - }); - refetch(); - } - dismissUpdateStatus(); - }, - }); - }; - - const showUpdateStatus = (sample: SampleTestModel) => { - setStatusDialog({ - show: true, - sample, - }); - }; - - const dismissUpdateStatus = () => { - setStatusDialog({ - show: false, - sample: {}, - }); - }; - - const parseExportData = (data: string) => { - const [header, ...rows] = data.trim().split("\n"); - const headerColumns = header.split(",").map((col) => col.trim()); - - return [ - header, - ...rows.map((row) => { - const columns = row.split(",").map((field, index) => { - const header = headerColumns[index]; - - if (header === "Patient Age") { - return field.trim(); - } - - if (["Date of Sample", "Date of Result"].includes(header)) { - const formattedDate = formatDateTime(field.trim()); - return formattedDate === "Invalid Date" ? "" : formattedDate; - } - return field.includes(",") ? `"${field.trim()}"` : field.trim(); - }); - - return columns.join(","); - }), - ].join("\n"); - }; - - let sampleList: any[] = []; - if (sampeleData?.count) { - sampleList = sampeleData.results.map((item) => { - const status = String(item.status) as keyof typeof SAMPLE_FLOW_RULES; - const statusText = SAMPLE_TEST_STATUS.find( - (i) => i.text === status, - )?.desc; - return ( -
    -
    -
    -
    -
    -
    - {item.patient_name} -
    -
    - {item.sample_type && ( - - Type: {item.sample_type} - - )} -
    -
    - {item.result !== "AWAITING" && ( -
    - - Result:{" "} - - {item.result ? item.result.toLocaleLowerCase() : "-"} -
    - )} -
    - - Status:{" "} - - {statusText} -
    - {item.facility_object && ( -
    - - Facility:{" "} - - {item.facility_object.name} -
    - )} - {item.fast_track && ( -
    - - Fast track:{" "} - - {item.fast_track} -
    - )} - {item.patient_has_confirmed_contact && ( -
    - - Contact:{" "} - - Confirmed carrier - -
    - )} - {item.patient_has_suspected_contact && - !item.patient_has_confirmed_contact && ( -
    - - Contact:{" "} - - Suspected carrier - -
    - )} - {item.has_sari && ( -
    - - SARI:{" "} - - Severe Acute Respiratory illness - -
    - )} - {item.has_ari && !item.has_sari && ( -
    - ARI: - Acute Respiratory illness - -
    - )} -
    - -
    -
    - Date of Sample:{" "} - {item.date_of_sample - ? formatDateTime(item.date_of_sample) - : "Not Available"} -
    - -
    - Date of Result:{" "} - {item.date_of_result - ? formatDateTime(item.date_of_result) - : "Not Available"} -
    -
    - -
    - {item.result === "AWAITING" && ( -
    - -
    - )} - - -
    -
    -
    -
    - ); - }); - } - - if (isLoading || !sampeleData) { - manageSamples = ( -
    - -
    - ); - } else if (sampeleData?.count) { - manageSamples = ( - <> - {sampleList} - - - ); - } else if (sampeleData?.count === 0) { - manageSamples = ( -
    -
    - No Sample Tests Found -
    -
    - ); - } - - return ( - { - const { data } = await request(routes.getTestSampleList, { - query: { ...qParams, csv: true }, - }); - return data ?? null; - }} - parse={parseExportData} - filenamePrefix="samples" - /> - } - > - {statusDialog.show && ( - - )} -
    -
    -
    - -
    - -
    - updateQuery({ [e.name]: e.value })} - placeholder="Search patient" - /> - updateQuery({ [e.name]: e.value })} - placeholder="Search by district" - secondary - /> -
    - - advancedFilter.setShow(true)} /> - -
    - [ - badge("Patient Name", "patient_name"), - badge("District Name", "district_name"), - value( - "Status", - "status", - SAMPLE_TEST_STATUS.find( - (status) => status.id == qParams.status, - )?.text.replaceAll("_", " ") || "", - ), - value( - "Result", - "result", - SAMPLE_TEST_RESULT.find((result) => result.id == qParams.result) - ?.text || "", - ), - value( - "Sample Test Type", - "sample_type", - SAMPLE_TYPE_CHOICES.find( - (type) => type.id === qParams.sample_type, - )?.text || "", - ), - value( - "Facility", - "facility", - qParams.facility ? facilityData?.name || "" : "", - ), - ]} - /> -
    -
    -
    {manageSamples}
    -
    -
    - ); -} diff --git a/src/components/Patient/UpdateStatusDialog.tsx b/src/components/Patient/UpdateStatusDialog.tsx deleted file mode 100644 index e9a767847aa..00000000000 --- a/src/components/Patient/UpdateStatusDialog.tsx +++ /dev/null @@ -1,230 +0,0 @@ -import { useEffect, useReducer } from "react"; -import { useTranslation } from "react-i18next"; - -import CareIcon from "@/CAREUI/icons/CareIcon"; - -import { Button } from "@/components/ui/button"; - -import ConfirmDialog from "@/components/Common/ConfirmDialog"; -import { LinearProgressWithLabel } from "@/components/Files/FileUpload"; -import CheckBoxFormField from "@/components/Form/FormFields/CheckBoxFormField"; -import { SelectFormField } from "@/components/Form/FormFields/SelectFormField"; -import TextFormField from "@/components/Form/FormFields/TextFormField"; -import { FieldChangeEvent } from "@/components/Form/FormFields/Utils"; - -import useFileUpload from "@/hooks/useFileUpload"; - -import { - SAMPLE_FLOW_RULES, - SAMPLE_TEST_RESULT, - SAMPLE_TEST_STATUS, -} from "@/common/constants"; - -import * as Notification from "@/Utils/Notifications"; - -import { SampleTestModel } from "./models"; - -interface Props { - sample: SampleTestModel; - handleOk: (sample: SampleTestModel, status: number, result: number) => void; - handleCancel: () => void; -} - -const statusChoices = [...SAMPLE_TEST_STATUS]; -const statusFlow = { ...SAMPLE_FLOW_RULES }; - -const initForm: any = { - confirm: false, - status: 0, - result: 0, - disabled: true, -}; - -const initialState = { - form: { ...initForm }, -}; - -const updateStatusReducer = (state = initialState, action: any) => { - switch (action.type) { - case "set_form": { - return { - ...state, - form: action.form, - }; - } - default: - return state; - } -}; -const UpdateStatusDialog = (props: Props) => { - const { t } = useTranslation(); - const { sample, handleOk, handleCancel } = props; - const [state, dispatch] = useReducer(updateStatusReducer, initialState); - - const fileUpload = useFileUpload({ - type: "SAMPLE_MANAGEMENT", - allowedExtensions: ["pdf", "jpg", "jpeg", "png"], - allowNameFallback: true, - }); - const currentStatus = SAMPLE_TEST_STATUS.find( - (i) => i.text === sample.status, - ); - - const status = String(sample.status) as keyof typeof SAMPLE_FLOW_RULES; - const validStatusChoices = statusChoices.filter( - (i) => status && statusFlow[status] && statusFlow[status].includes(i.text), - ); - - useEffect(() => { - const form = { ...state.form }; - form.status = 0; - dispatch({ type: "set_form", form }); - }, []); - - const okClicked = () => { - handleOk(sample, state.form.status, state.form.result); - dispatch({ type: "set_form", form: initForm }); - }; - - const cancelClicked = () => { - handleCancel(); - dispatch({ type: "set_form", form: initForm }); - }; - - const handleChange = ({ name, value }: FieldChangeEvent) => { - const form = { ...state.form }; - form[name] = name === "status" || name === "result" ? Number(value) : value; - form.disabled = - !form.status || !form.confirm || (form.status === 7 && !form.result); - dispatch({ type: "set_form", form }); - }; - - const handleUpload = async () => { - if (fileUpload.files.length > 0) { - if (!fileUpload.fileNames[0]) { - Notification.Error({ - msg: "Please enter a file name before uploading", - }); - return; - } - if (sample.id) { - await fileUpload.handleFileUpload(sample.id); - if (!fileUpload.error) { - return; - } else { - Notification.Error({ msg: `Upload failed: ${fileUpload.error}` }); - } - } else { - Notification.Error({ msg: "Sample ID is missing" }); - } - } else { - Notification.Error({ msg: "No file selected for upload" }); - } - }; - - return ( - -
    - - i.desc} - optionValue={(i) => i.id} - onChange={handleChange} - /> - {Number(state.form.status) === 7 && ( - <> - i.text} - optionValue={(i) => i.id} - onChange={handleChange} - /> - - {t("upload_report")}: - - {fileUpload.files[0] ? ( -
    -
    - - - {fileUpload.files[0].name} - -
    - fileUpload.setFileName(e.value)} - error={fileUpload.error || undefined} - required - /> -
    - - -
    - {!!fileUpload.progress && ( - - )} -
    - ) : ( -
    - -
    - )} - - )} - -
    -
    - ); -}; - -export default UpdateStatusDialog; diff --git a/src/components/Patient/models.tsx b/src/components/Patient/models.tsx index 2b1c3c84d0c..dc3a0f5f681 100644 --- a/src/components/Patient/models.tsx +++ b/src/components/Patient/models.tsx @@ -143,137 +143,6 @@ export interface PatientModel { age?: string; } -export interface SampleTestModel { - patient_object?: PatientModel; - atypical_presentation?: string; - diagnosis?: string; - diff_diagnosis?: string; - testing_facility?: string; - doctor_name?: string; - etiology_identified?: string; - has_ari?: boolean; - has_sari?: boolean; - is_atypical_presentation?: boolean; - is_unusual_course?: boolean; - sample_type?: string; - sample_type_other?: string; - id?: string; - status?: string; - result?: string; - icmr_category?: string; - icmr_label?: string; - date_of_sample?: string; - date_of_result?: string; - consultation?: number; - patient_name?: string; - patient_has_sari?: boolean; - patient_has_confirmed_contact?: boolean; - patient_has_suspected_contact?: boolean; - patient_travel_history?: string[]; - facility?: number; - facility_object?: { - id: number; - name: string; - facility_type?: { id: number; name: string }; - }; - patient?: number; - fast_track?: string; - isFastTrack?: boolean; - flow?: Array; - created_by?: any; - last_edited_by?: any; - created_date?: string; - modified_date?: string; -} - -export interface SampleReportModel { - id?: number; - personal_details?: { - name?: string; - gender?: string; - age_years?: number; - age_months?: number; - date_of_birth?: string; - phone_number?: string; - email?: string; - address?: string; - pincode?: string; - passport_no?: string; - aadhaar_no?: string; - local_body_name?: string; - district_name?: string; - state_name?: string; - }; - specimen_details?: { - created_date?: string; - sample_type?: string; - collection_type?: string; - icmr_category?: string; - icmr_label?: string; - is_repeated_sample?: boolean; - lab_name?: string; - lab_pincode?: string; - }; - patient_category?: { - symptomatic_international_traveller?: boolean; - symptomatic_contact_of_confirmed_case?: boolean; - symptomatic_healthcare_worker?: boolean; - hospitalized_sari_patient?: boolean; - asymptomatic_family_member_of_confirmed_case?: boolean; - asymptomatic_healthcare_worker_without_protection?: boolean; - }; - exposure_history?: { - has_travel_to_foreign_last_14_days?: boolean; - places_of_travel?: Array; - travel_start_date?: string; - travel_end_date?: string; - contact_with_confirmed_case?: boolean; - contact_case_name?: string; - was_quarantined?: boolean; - quarantined_type?: string; - healthcare_worker?: boolean; - }; - medical_conditions?: { - date_of_onset_of_symptoms?: string; - symptoms?: Array; - has_sari?: boolean; - has_ari?: boolean; - medical_conditions_list?: Array; - hospitalization_date?: string; - diagnosis?: string; - diff_diagnosis?: string; - etiology_identified?: string; - is_atypical_presentation?: boolean; - is_unusual_course?: boolean; - hospital_phone_number?: string; - hospital_name?: string; - doctor_name?: string; - hospital_pincode?: string; - }; -} - -export interface SampleListModel { - id?: number; - patient_name?: string; - patient_has_sari?: boolean; - patient_has_confirmed_contact?: boolean; - patient_has_suspected_contact?: boolean; - patient_travel_history?: string; - facility?: number; - facility_object?: { - id: number; - name: string; - facility_type?: { id: number; name: string }; - }; - status?: string; - result?: string; - patient?: number; - consultation?: number; - date_of_sample?: string; - date_of_result?: string; - fast_track?: string; -} - export const DailyRoundTypes = [ "NORMAL", "COMMUNITY_NURSES_LOG", diff --git a/src/hooks/useActiveLink.ts b/src/hooks/useActiveLink.ts index b52b15600dd..609a518bc6d 100644 --- a/src/hooks/useActiveLink.ts +++ b/src/hooks/useActiveLink.ts @@ -12,7 +12,6 @@ const activeLinkPriority = { "/patient/": "/patients", "/death_report": "/patients", "/assets": "/assets", - "/sample": "/sample", "/shifting": "/shifting", "/resource": "/resource", "/users": "/users", From b1470271e66b0af5e7fc6e1ac991b021cb51cec7 Mon Sep 17 00:00:00 2001 From: Bodhish Thomas Date: Sun, 15 Dec 2024 22:33:18 +0530 Subject: [PATCH 21/21] Cleanup capacity related fields from facility (#9436) Co-authored-by: rithviknishad Co-authored-by: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> --- .../e2e/facility_spec/FacilityCreation.cy.ts | 374 ++------- .../e2e/facility_spec/FacilityHomepage.cy.ts | 18 - .../e2e/facility_spec/FacilityManage.cy.ts | 64 -- .../e2e/patient_spec/PatientHomepage.cy.ts | 4 - .../e2e/resource_spec/ResourcesHomepage.cy.ts | 8 +- .../pageobject/Facility/FacilityCreation.ts | 269 +----- cypress/pageobject/Facility/FacilityHome.ts | 7 +- cypress/pageobject/Facility/FacilityManage.ts | 34 - cypress/pageobject/Resource/ResourcePage.ts | 4 + cypress/pageobject/utils/constants.ts | 116 ++- cypress/support/commands.ts | 18 + cypress/support/index.ts | 5 + package-lock.json | 8 +- package.json | 2 +- src/Routers/routes/FacilityRoutes.tsx | 7 - src/Utils/request/api.tsx | 109 +-- src/components/ExternalResult/models.ts | 18 - src/components/Facility/BedCapacity.tsx | 301 ------- src/components/Facility/BedTypeCard.tsx | 181 ---- .../Facility/FacilityBedCapacity.tsx | 126 --- src/components/Facility/FacilityCreate.tsx | 776 +++++------------- src/components/Facility/FacilityHome.tsx | 47 +- .../Facility/FacilityHomeTriage.tsx | 89 -- src/components/Facility/FacilityList.tsx | 35 +- src/components/Facility/FacilityStaffList.tsx | 138 ---- src/components/Facility/StaffCapacity.tsx | 241 ------ src/components/Facility/StaffCountCard.tsx | 118 --- src/components/Facility/TriageForm.tsx | 321 -------- src/components/Facility/models.tsx | 33 - src/components/Patient/PatientRegister.tsx | 4 +- 30 files changed, 459 insertions(+), 3016 deletions(-) delete mode 100644 src/components/ExternalResult/models.ts delete mode 100644 src/components/Facility/BedCapacity.tsx delete mode 100644 src/components/Facility/BedTypeCard.tsx delete mode 100644 src/components/Facility/FacilityBedCapacity.tsx delete mode 100644 src/components/Facility/FacilityHomeTriage.tsx delete mode 100644 src/components/Facility/FacilityStaffList.tsx delete mode 100644 src/components/Facility/StaffCapacity.tsx delete mode 100644 src/components/Facility/StaffCountCard.tsx delete mode 100644 src/components/Facility/TriageForm.tsx diff --git a/cypress/e2e/facility_spec/FacilityCreation.cy.ts b/cypress/e2e/facility_spec/FacilityCreation.cy.ts index f644c9829d3..d2893166745 100644 --- a/cypress/e2e/facility_spec/FacilityCreation.cy.ts +++ b/cypress/e2e/facility_spec/FacilityCreation.cy.ts @@ -1,20 +1,25 @@ -import { advanceFilters } from "pageobject/utils/advanceFilterHelpers"; +import { + generateFacilityName, + generatePhoneNumber, + generateRandomAddress, +} from "pageobject/utils/constants"; import FacilityPage, { FacilityData, } from "../../pageobject/Facility/FacilityCreation"; -import FacilityHome from "../../pageobject/Facility/FacilityHome"; import LoginPage from "../../pageobject/Login/LoginPage"; -import ManageUserPage from "../../pageobject/Users/ManageUserPage"; import { nonAdminRoles } from "../../pageobject/utils/userConfig"; -describe("Facility Creation", () => { - let facilityUrl1: string; +describe("Facility Creation with multiple user roles", () => { const facilityPage = new FacilityPage(); const loginPage = new LoginPage(); - const facilityHome = new FacilityHome(); - const manageUserPage = new ManageUserPage(); - const facilityFeature = [ + const facilityName = generateFacilityName(); + const facilityNumber = generatePhoneNumber(); + const facilityAddress = generateRandomAddress(false); + const facilityUpdatedNumber = generatePhoneNumber(); + const facilityUpdatedName = generateFacilityName(); + const facilityUpdatedAddress = generateRandomAddress(true); + const facilityFeatures = [ "CT Scan", "X-Ray", "Maternity Care", @@ -22,22 +27,6 @@ describe("Facility Creation", () => { "Operation Theater", "Blood Bank", ]; - const bedCapacity = "10"; - const bedOccupancy = "5"; - const oxygenCapacity = "100"; - const oxygenExpected = "80"; - const totalCapacity = "20"; - const totalOccupancy = "10"; - const doctorCapacity = "5"; - const totalDoctor = "10"; - const facilityName = "Cypress Facility"; - const facilityName2 = "Dummy Facility 40"; - const facilityAddress = "cypress address"; - const facilityUpdateAddress = "cypress updated address"; - const facilityNumber = "9898469865"; - const triageDate = "02122023"; - const initialTriageValue = "60"; - const modifiedTriageValue = "50"; const facilityErrorMessage = [ "Required", "Required", @@ -50,22 +39,11 @@ describe("Facility Creation", () => { "Required", "Invalid Phone Number", ]; - const bedErrorMessage = [ - "This field is required", - "Total capacity cannot be 0", - "This field is required", - ]; - const doctorErrorMessage = [ - "This field is required", - "This field is required", - ]; - const triageErrorMessage = ["This field is required"]; const facilityType = "Primary Health Centres"; const testFacilityData: FacilityData = { basic: { name: facilityName, type: facilityType, - features: facilityFeature, address: facilityAddress, phoneNumber: facilityNumber, location: "Kochi, Kerala", @@ -77,44 +55,6 @@ describe("Facility Creation", () => { localBody: "Aluva", ward: "4", }, - oxygen: { - capacity: oxygenCapacity, - expected: oxygenExpected, - bType: { - capacity: oxygenCapacity, - expected: oxygenExpected, - }, - cType: { - capacity: oxygenCapacity, - expected: oxygenExpected, - }, - dType: { - capacity: oxygenCapacity, - expected: oxygenExpected, - }, - }, - beds: [ - { - type: "Oxygen Supported Bed", - totalCapacity: bedCapacity, - occupied: bedOccupancy, - }, - { - type: "Ordinary Bed", - totalCapacity: bedCapacity, - occupied: bedOccupancy, - }, - ], - doctors: [ - { - specialization: "General Medicine", - count: doctorCapacity, - }, - { - specialization: "Pulmonology", - count: doctorCapacity, - }, - ], }; before(() => { @@ -128,262 +68,72 @@ describe("Facility Creation", () => { cy.awaitUrl("/facility"); }); - it("Verify Facility Triage Function", () => { - // mandatory field error throw - facilityHome.typeFacilitySearch(facilityName2); - advanceFilters.verifyFilterBadgePresence( - "Facility/District Name", - facilityName2, - true, - ); - facilityHome.assertFacilityInCard(facilityName2); - facilityHome.verifyURLContains(facilityName2); - facilityPage.visitAlreadyCreatedFacility(); - facilityPage.scrollToFacilityTriage(); - facilityPage.clickAddFacilityTriage(); - manageUserPage.clickSubmit(); - cy.verifyErrorMessages(triageErrorMessage); - // create a entry and verify reflection - facilityPage.fillEntryDate(triageDate); - facilityPage.fillTriageEntryFields( - initialTriageValue, - initialTriageValue, - initialTriageValue, - initialTriageValue, - initialTriageValue, - ); - manageUserPage.clickSubmit(); - // edit the entry and verify reflection - facilityPage.scrollToFacilityTriage(); - facilityPage.verifyTriageTableContains(initialTriageValue); - facilityPage.clickEditButton(); - facilityPage.fillTriageEntryFields( - modifiedTriageValue, - modifiedTriageValue, - modifiedTriageValue, - modifiedTriageValue, - modifiedTriageValue, - ); - manageUserPage.clickSubmit(); - facilityPage.scrollToFacilityTriage(); - facilityPage.verifyTriageTableContains(modifiedTriageValue); - // validate error of filling data on same date already data exist and verify reflection - facilityPage.scrollToFacilityTriage(); - facilityPage.clickAddFacilityTriage(); - facilityPage.fillEntryDate(triageDate); - facilityPage.clickButtonsMultipleTimes("button#submit"); - }); - - it("Create a new facility with multiple bed and doctor capacity", () => { - // create facility with multiple capacity and verify form error message for facility form + it("Create a new facility with all fields | Edit Existing Data | Verify its reflection", () => { + // Create a new facility facilityPage.visitCreateFacilityPage(); - facilityPage.submitForm(); - cy.verifyErrorMessages(facilityErrorMessage); - facilityPage.fillBasicDetails(testFacilityData.basic); + facilityPage.fillBasicDetails({ + ...testFacilityData.basic, + features: facilityFeatures, + }); facilityPage.fillLocationDetails(testFacilityData.location); - facilityPage.fillOxygenDetails(testFacilityData.oxygen); - facilityPage.submitForm(); - cy.closeNotification(); - // add the bed capacity - facilityPage.selectBedType("Oxygen Supported Bed"); - facilityPage.fillTotalCapacity(bedCapacity); - facilityPage.fillCurrentlyOccupied(bedOccupancy); - facilityPage.clickbedcapcityaddmore(); - cy.closeNotification(); - facilityPage.selectBedType("Ordinary Bed"); - facilityPage.fillTotalCapacity(bedCapacity); - facilityPage.fillCurrentlyOccupied(bedOccupancy); - facilityPage.clickbedcapcityaddmore(); - cy.closeNotification(); - facilityPage.getTotalBedCapacity().contains(totalCapacity); - facilityPage.getTotalBedCapacity().contains(totalOccupancy); - facilityPage.clickcancelbutton(); - // create multiple bed capacity and verify card reflection - facilityPage.selectAreaOfSpecialization("General Medicine"); - facilityPage.fillDoctorCount(doctorCapacity); - facilityPage.clickdoctorcapacityaddmore(); - cy.closeNotification(); - facilityPage.selectAreaOfSpecialization("Pulmonology"); - facilityPage.fillDoctorCount(doctorCapacity); - facilityPage.clickdoctorcapacityaddmore(); - cy.closeNotification(); - facilityPage.getTotalDoctorCapacity().contains(doctorCapacity); - facilityPage.clickcancelbutton(); - facilityPage.verifyfacilitynewurl(); - // verify the facility card - facilityPage.getFacilityName().contains(facilityName).should("be.visible"); - facilityPage - .getAddressDetailsView() - .contains(facilityAddress) - .should("be.visible"); - facilityPage - .getPhoneNumberView() - .contains(facilityNumber) - .should("be.visible"); - facilityPage - .getFacilityAvailableFeatures() - .invoke("text") - .then((text) => { - facilityFeature.forEach((feature) => { - expect(text).to.contain(feature); - }); - }); - facilityPage.getFacilityOxygenInfo().scrollIntoView(); - facilityPage - .getFacilityOxygenInfo() - .contains(oxygenCapacity) - .should("be.visible"); - facilityPage.getFacilityTotalBedCapacity().scrollIntoView(); - facilityPage.getFacilityTotalBedCapacity().contains(totalCapacity); - facilityPage.getFacilityTotalBedCapacity().contains(totalOccupancy); - facilityPage.getFacilityTotalDoctorCapacity().scrollIntoView(); - facilityPage.getFacilityTotalDoctorCapacity().contains(totalDoctor); - // verify the delete functionality - cy.get("#manage-facility-dropdown button").scrollIntoView(); - facilityPage.clickManageFacilityDropdown(); - facilityPage.clickDeleteFacilityOption(); - facilityPage.confirmDeleteFacility(); - cy.verifyNotification("Facility deleted successfully"); - }); - - it("Create a new facility with single bed and doctor capacity", () => { - const singleCapacityData = { - ...testFacilityData, - // Remove features, location, and oxygen that aren't used in this test - basic: { - ...testFacilityData.basic, - features: undefined, - location: undefined, - }, - oxygen: undefined, - // Override with single bed capacity - beds: [ - { - type: "Oxygen Supported Bed", - totalCapacity: oxygenCapacity, - occupied: oxygenExpected, - }, - ], - // Override with single doctor capacity - doctors: [ - { - specialization: "General Medicine", - count: doctorCapacity, - }, - ], - }; - facilityPage.createNewFacility(singleCapacityData); - // verify the created facility details - facilityPage.getFacilityName().contains(facilityName).should("be.visible"); - facilityPage - .getAddressDetailsView() - .contains(facilityAddress) - .should("be.visible"); - facilityPage - .getPhoneNumberView() - .contains(facilityNumber) - .should("be.visible"); - // verify the facility homepage - facilityHome.navigateToFacilityHomepage(); - facilityHome.typeFacilitySearch(facilityName); - advanceFilters.verifyFilterBadgePresence( - "Facility/District Name", + facilityPage.selectLocation("Kochi, Kerala"); + facilityPage.clickSaveFacilityButton(); + facilityPage.verifyFacilityCreatedNotification(); + // verify the facility card info + cy.verifyContentPresence("#facility-details-card", [ facilityName, - true, - ); - facilityHome.assertFacilityInCard(facilityName); - facilityHome.verifyURLContains(facilityName); - }); - - it("Create a new facility with no bed and doctor capacity", () => { - const noCapacityData = { - ...testFacilityData, - basic: { - ...testFacilityData.basic, - features: undefined, - location: undefined, - }, - oxygen: undefined, - beds: [], - doctors: [], - }; - facilityPage.visitCreateFacilityPage(); - facilityPage.fillBasicDetails(noCapacityData.basic); - facilityPage.fillLocationDetails(noCapacityData.location); - facilityPage.submitForm(); - // add no bed capacity and verify form error message - facilityPage.isVisibleselectBedType(); - facilityPage.saveAndExitBedCapacityForm(); - cy.verifyErrorMessages(bedErrorMessage); - facilityPage.clickcancelbutton(); - // add no doctor capacity and verify form error message - facilityPage.isVisibleAreaOfSpecialization(); - facilityPage.clickdoctorcapacityaddmore(); - cy.verifyErrorMessages(doctorErrorMessage); - facilityPage.clickcancelbutton(); - cy.url().then((newUrl) => { - facilityUrl1 = newUrl; - }); - // verify the created facility details - facilityPage.getFacilityName().contains(facilityName).should("be.visible"); - facilityPage - .getAddressDetailsView() - .contains(facilityAddress) - .should("be.visible"); - facilityPage - .getPhoneNumberView() - .contains(facilityNumber) - .should("be.visible"); - }); - - it("Update the existing facility", () => { - // update a existing dummy data facility - facilityPage.visitUpdateFacilityPage(facilityUrl1); + facilityAddress, + facilityNumber, + ]); + // Edit the facility data facilityPage.clickManageFacilityDropdown(); facilityPage.clickUpdateFacilityOption(); - facilityPage.selectFacilityType(facilityType); - facilityPage.fillAddress(facilityUpdateAddress); - facilityPage.fillOxygenCapacity(oxygenCapacity); - facilityPage.fillExpectedOxygenRequirement(oxygenExpected); - facilityPage.selectLocation("Kochi, Kerala"); - facilityPage.submitForm(); - cy.url().should("not.include", "/update"); - // verify the updated data - facilityPage.getFacilityOxygenInfo().scrollIntoView(); - facilityPage - .getFacilityOxygenInfo() - .contains(oxygenCapacity) - .should("be.visible"); - facilityPage.getAddressDetailsView().scrollIntoView(); - facilityPage - .getAddressDetailsView() - .contains(facilityUpdateAddress) - .should("be.visible"); + facilityPage.typeFacilityName(facilityUpdatedName, true); + facilityPage.typeFacilityPhoneNumber(facilityUpdatedNumber, true); + facilityPage.typeFacilityAddress(facilityUpdatedAddress, true); + facilityPage.clickUpdateFacilityButton(); + facilityPage.verifyFacilityUpdatedNotification(); + // verify the facility card updated info + cy.verifyContentPresence("#facility-details-card", [ + facilityUpdatedName, + facilityUpdatedAddress, + facilityUpdatedNumber, + ]); }); - it("Configure the existing facility", () => { - facilityPage.visitUpdateFacilityPage(facilityUrl1); + it("Create a new facility with only mandatory fields | Delete the facility", () => { + // Create a new facility + facilityPage.visitCreateFacilityPage(); + facilityPage.fillBasicDetails(testFacilityData.basic); + facilityPage.fillLocationDetails(testFacilityData.location); + facilityPage.clickSaveFacilityButton(); + facilityPage.verifyFacilityCreatedNotification(); + // verify the facility card info + cy.verifyContentPresence("#facility-details-card", [ + facilityName, + facilityAddress, + facilityNumber, + ]); + // verify the delete facility functionality facilityPage.clickManageFacilityDropdown(); - facilityPage.clickConfigureFacilityOption(); - facilityPage.fillMiddleWareAddress("dev_middleware.coronasafe.live"); - facilityPage.clickupdateMiddleWare(); - facilityPage.verifySuccessNotification( - "Facility middleware updated successfully", - ); + facilityPage.clickDeleteFacilityOption(); + facilityPage.confirmDeleteFacility(); + cy.verifyNotification(`${facilityName} deleted successfully`); }); it("Should display error when district admin tries to create facility in a different district", () => { + // Verify the entire form error message facilityPage.visitCreateFacilityPage(); - facilityPage.fillFacilityName(facilityName); - facilityPage.selectFacilityType(facilityType); + facilityPage.clickSaveFacilityButton(); + cy.verifyErrorMessages(facilityErrorMessage); + // Verify the user access based error message + facilityPage.fillBasicDetails(testFacilityData.basic); facilityPage.fillPincode("682001"); facilityPage.selectStateOnPincode("Kerala"); facilityPage.selectDistrictOnPincode("Kottayam"); facilityPage.selectLocalBody("Arpookara"); facilityPage.selectWard("5"); - facilityPage.fillAddress(facilityAddress); - facilityPage.fillPhoneNumber(facilityNumber); - facilityPage.submitForm(); + facilityPage.clickSaveFacilityButton(); facilityPage.verifyErrorNotification( "You do not have permission to perform this action.", ); diff --git a/cypress/e2e/facility_spec/FacilityHomepage.cy.ts b/cypress/e2e/facility_spec/FacilityHomepage.cy.ts index 680ce6fa2ce..0aa8518a6d1 100644 --- a/cypress/e2e/facility_spec/FacilityHomepage.cy.ts +++ b/cypress/e2e/facility_spec/FacilityHomepage.cy.ts @@ -21,8 +21,6 @@ describe("Facility Homepage Function", () => { const patientPage = new PatientPage(); const facilityLocation = new FacilityLocation(); const facilitiesAlias = "downloadFacilitiesCSV"; - const doctorsAlias = "downloadDoctorsCSV"; - const triagesAlias = "downloadTriagesCSV"; const facilityName = "Dummy Facility 40"; const facilityLocaion = "Dummy Location"; const stateName = "Kerala"; @@ -118,23 +116,7 @@ describe("Facility Homepage Function", () => { // Verify Facility Export facilityHome.csvDownloadIntercept(facilitiesAlias, ""); facilityHome.clickExportButton(); - facilityHome.clickMenuItem("Facilities"); facilityHome.verifyDownload(facilitiesAlias); - // Verify Doctor Export - facilityHome.csvDownloadIntercept(doctorsAlias, "&doctors"); - facilityHome.clickExportButton(); - facilityHome.clickMenuItem("Doctors"); - facilityHome.verifyDownload(doctorsAlias); - // Verify Triage Export - facilityHome.csvDownloadIntercept(triagesAlias, "&triage"); - facilityHome.clickExportButton(); - facilityHome.clickMenuItem("Triages"); - facilityHome.verifyDownload(triagesAlias); - }); - - it("Verify Capacity Export Functionality", () => { - facilityHome.clickExportButton(); - facilityHome.clickMenuItem("Capacities"); }); it("Verify Facility Detail page redirection to CNS and Live Minitoring ", () => { diff --git a/cypress/e2e/facility_spec/FacilityManage.cy.ts b/cypress/e2e/facility_spec/FacilityManage.cy.ts index 9f1523768c1..3930f470160 100644 --- a/cypress/e2e/facility_spec/FacilityManage.cy.ts +++ b/cypress/e2e/facility_spec/FacilityManage.cy.ts @@ -21,12 +21,6 @@ describe("Facility Manage Functions", () => { /Health Facility config updated successfully|Health ID registration failed/; const facilityHfrId = "IN180000018"; const facilityUpdatedHfrId = "IN180000020"; - const doctorCapacity = "5"; - const doctorModifiedCapacity = "7"; - const totalCapacity = "100"; - const currentOccupied = "80"; - const totalUpdatedCapacity = "120"; - const currentUpdatedOccupied = "100"; before(() => { loginPage.loginByRole("districtAdmin"); @@ -116,64 +110,6 @@ describe("Facility Manage Functions", () => { facilityManage.verifyHfrIdValue(facilityUpdatedHfrId); }); - it("Modify doctor capacity in Facility detail page", () => { - // Add a doctor capacity - facilityManage.clickFacilityAddDoctorTypeButton(); - facilityPage.selectAreaOfSpecialization("Pulmonology"); - facilityPage.fillDoctorCount(doctorCapacity); - facilityPage.saveAndExitDoctorForm(); - facilityManage.verifySuccessMessageVisibilityAndContent( - "Staff count added successfully", - ); - facilityManage.verifyTotalDoctorCapacity(doctorCapacity); - // edit a existing doctor - facilityManage.clickEditFacilityDoctorCapacity(); - facilityPage.fillDoctorCount(doctorModifiedCapacity); - facilityPage.clickdoctorcapacityaddmore(); - facilityManage.verifySuccessMessageVisibilityAndContent( - "Staff count updated successfully", - ); - facilityManage.verifyTotalDoctorCapacity(doctorModifiedCapacity); - // delete a bed - facilityManage.clickDeleteFacilityDoctorCapacity(); - facilityManage.clickButtonWithText("Delete"); - facilityManage.verifySuccessMessageVisibilityAndContent( - "Staff specialization type deleted successfully", - ); - }); - - it("Modify bed capacity in Facility detail page", () => { - // add multiple new bed capacity - facilityManage.clickFacilityAddBedTypeButton(); - facilityPage.selectBedType("Isolation Bed"); - facilityPage.fillTotalCapacity(totalCapacity); - facilityPage.fillCurrentlyOccupied(currentOccupied); - facilityPage.saveAndExitBedCapacityForm(); - facilityManage.verifySuccessMessageVisibilityAndContent( - "Bed capacity added successfully", - ); - cy.closeNotification(); - facilityManage.verifyFacilityBedCapacity(totalCapacity); - facilityManage.verifyFacilityBedCapacity(currentOccupied); - // edit a existing bed - facilityManage.clickEditFacilityBedCapacity(); - facilityPage.fillTotalCapacity(totalUpdatedCapacity); - facilityPage.fillCurrentlyOccupied(currentUpdatedOccupied); - facilityPage.clickbedcapcityaddmore(); - facilityManage.verifySuccessMessageVisibilityAndContent( - "Bed capacity updated successfully", - ); - cy.closeNotification(); - facilityManage.verifyFacilityBedCapacity(totalUpdatedCapacity); - facilityManage.verifyFacilityBedCapacity(currentUpdatedOccupied); - // delete a bed - facilityManage.clickDeleteFacilityBedCapacity(); - facilityManage.clickButtonWithText("Delete"); - facilityManage.verifySuccessMessageVisibilityAndContent( - "Bed type deleted successfully", - ); - }); - afterEach(() => { cy.saveLocalStorage(); }); diff --git a/cypress/e2e/patient_spec/PatientHomepage.cy.ts b/cypress/e2e/patient_spec/PatientHomepage.cy.ts index a120e282a2d..8949fc3e324 100644 --- a/cypress/e2e/patient_spec/PatientHomepage.cy.ts +++ b/cypress/e2e/patient_spec/PatientHomepage.cy.ts @@ -54,7 +54,6 @@ describe("Patient Homepage present functionalities", () => { patientHome.verifyPatientAdmittedBeforeDate(patientToDateBadge); patientHome.verifyPatientAdmittedAfterDate(patientFromDateBadge); cy.clearAllFilters(); - patientHome.verifyTotalPatientCount("1"); }); it("Facility Geography based advance filters applied in the patient tab", () => { @@ -71,7 +70,6 @@ describe("Patient Homepage present functionalities", () => { patientHome.verifyFacilityLsgBadgeContent(facilityLsgBody); patientHome.verifyFacilityDistrictContent(facilityDistrict); cy.clearAllFilters(); - patientHome.verifyTotalPatientCount("1"); }); it("Patient diagnosis based advance filters applied in the patient tab", () => { @@ -104,7 +102,6 @@ describe("Patient Homepage present functionalities", () => { patientHome.verifyDifferentialDiagnosisBadgeContent(patientIcdDiagnosis); // Clear the badges and verify the patient count along with badges cy.clearAllFilters(); - patientHome.verifyTotalPatientCount("1"); // Apply Any and confirmed diagonsis to verify patient count 17 advanceFilters.clickAdvancedFiltersButton(); patientHome.selectAnyIcdDiagnosis(patientIcdDiagnosis, patientIcdDiagnosis); @@ -142,7 +139,6 @@ describe("Patient Homepage present functionalities", () => { patientHome.verifyMedicoBadgeContent("false"); // Clear the badges and verify the patient count along with badges cy.clearAllFilters(); - patientHome.verifyTotalPatientCount("1"); }); it("Export the live patient list based on a date range", () => { diff --git a/cypress/e2e/resource_spec/ResourcesHomepage.cy.ts b/cypress/e2e/resource_spec/ResourcesHomepage.cy.ts index 23077a71ed8..160884978fd 100644 --- a/cypress/e2e/resource_spec/ResourcesHomepage.cy.ts +++ b/cypress/e2e/resource_spec/ResourcesHomepage.cy.ts @@ -20,14 +20,15 @@ describe("Resource Page", () => { beforeEach(() => { cy.restoreLocalStorage(); cy.clearLocalStorage(/filters--.+/); - cy.awaitUrl("/resource"); }); it("Checks if all download button works", () => { + resourcePage.navigationToResourcePage(); resourcePage.verifyDownloadButtonWorks(); }); it("Switch between active/completed", () => { + resourcePage.navigationToResourcePage(); resourcePage.spyResourceApi(); resourcePage.clickCompletedResources(); resourcePage.verifyCompletedResources(); @@ -37,6 +38,7 @@ describe("Resource Page", () => { }); it("Switch between list view and board view", () => { + resourcePage.navigationToResourcePage(); resourcePage.clickListViewButton(); resourcePage.clickBoardViewButton(); }); @@ -68,7 +70,7 @@ describe("Resource Page", () => { }); it("Update the status of resource", () => { - cy.visit(createdResource); + cy.awaitUrl(createdResource); resourcePage.clickUpdateStatus(); resourcePage.updateStatus("APPROVED"); resourcePage.clickSubmitButton(); @@ -78,7 +80,7 @@ describe("Resource Page", () => { }); it("Post comment for a resource", () => { - cy.visit(createdResource); + cy.awaitUrl(createdResource); resourcePage.addCommentForResource("Test comment"); resourcePage.clickPostCommentButton(); resourcePage.verifySuccessNotification("Comment added successfully"); diff --git a/cypress/pageobject/Facility/FacilityCreation.ts b/cypress/pageobject/Facility/FacilityCreation.ts index e59dfef09f3..9776433e523 100644 --- a/cypress/pageobject/Facility/FacilityCreation.ts +++ b/cypress/pageobject/Facility/FacilityCreation.ts @@ -16,31 +16,6 @@ export interface FacilityData { localBody: string; ward: string; }; - oxygen?: { - capacity: string; - expected: string; - bType?: { - capacity: string; - expected: string; - }; - cType?: { - capacity: string; - expected: string; - }; - dType?: { - capacity: string; - expected: string; - }; - }; - beds?: Array<{ - type: string; - totalCapacity: string; - occupied: string; - }>; - doctors?: Array<{ - specialization: string; - count: string; - }>; } class FacilityPage { @@ -60,15 +35,8 @@ class FacilityPage { advanceFilters.selectLocalBody(localBody); } - visitUpdateFacilityPage(url: string) { - cy.intercept("GET", "**/api/v1/facility/**").as("getFacilities"); - cy.visit(url); - cy.wait("@getFacilities").its("response.statusCode").should("eq", 200); - cy.get("#manage-facility-dropdown button").should("be.visible"); - } - - fillFacilityName(name: string) { - cy.get("#name").click().clear().click().type(name); + typeFacilityName(name: string, clearBeforeTyping: boolean = false) { + cy.typeIntoField("#name", name, { clearBeforeTyping }); } fillPincode(pincode: string) { @@ -80,90 +48,29 @@ class FacilityPage { cy.get("[role='option']").contains(ward).click(); } - fillAddress(address: string) { - cy.get("#address").click().type(address); - } - - fillPhoneNumber(phoneNumber: string) { - cy.get("#phone_number").type(phoneNumber); - } - - submitForm() { - cy.get("button#submit").click(); - } - - selectBedType(bedType: string) { - cy.clickAndSelectOption("div#bed-type button", bedType); - } - - isVisibleselectBedType() { - cy.get("div#bed-type button").should("be.visible"); - } - - fillTotalCapacity(capacity: string) { - cy.get("input#total-capacity").click().clear().click().type(capacity); - } - - fillCurrentlyOccupied(occupied: string) { - cy.get("input#currently-occupied").click().clear().click().type(occupied); - } - - saveAndExitBedCapacityForm() { - cy.get("button#bed-capacity-save-and-exit").click(); - } - - selectAreaOfSpecialization(area: string) { - cy.get("div#area-of-specialization button").click(); - cy.get("[role='option']").contains(area).click(); + typeFacilityAddress(address: string, clearBeforeTyping: boolean = false) { + cy.typeIntoField("#address", address, { clearBeforeTyping }); } - isVisibleAreaOfSpecialization() { - cy.get("div#area-of-specialization button").should("be.visible"); - } - - fillDoctorCount(count: string) { - cy.get("input#count").click().clear().click().type(count); - } - - fillOxygenCapacity(capacity: string) { - cy.get("#oxygen_capacity").click().clear().type(capacity); - } - - fillExpectedOxygenRequirement(requirement: string) { - cy.get("#expected_oxygen_requirement").click().clear().type(requirement); - } - - fillBTypeCylinderCapacity(capacity: string) { - cy.get("#type_b_cylinders").click().clear().type(capacity); - } - - fillExpectedBTypeCylinderRequirement(requirement: string) { - cy.get("#expected_type_b_cylinders").focus().clear(); - cy.get("#expected_type_b_cylinders").focus().type(requirement); - } - - fillCTypeCylinderCapacity(capacity: string) { - cy.get("#type_c_cylinders").click().clear().type(capacity); - } - - fillExpectedCTypeCylinderRequirement(requirement: string) { - cy.get("#expected_type_c_cylinders").focus().clear(); - cy.get("#expected_type_c_cylinders").focus().type(requirement); + typeFacilityPhoneNumber( + phoneNumber: string, + clearBeforeTyping: boolean = false, + ) { + cy.typeIntoField("#phone_number", phoneNumber, { clearBeforeTyping }); } - fillDTypeCylinderCapacity(capacity: string) { - cy.get("#type_d_cylinders").click().clear().type(capacity); + clickSaveFacilityButton() { + cy.verifyAndClickElement("#submit", "Save Facility"); } - fillExpectedDTypeCylinderRequirement(requirement: string) { - cy.get("#expected_type_d_cylinders").focus().clear(); - cy.get("#expected_type_d_cylinders").focus().type(requirement); + verifyFacilityCreatedNotification() { + cy.verifyNotification("Facility added successfully"); + cy.closeNotification(); } - saveAndExitDoctorForm() { - cy.intercept("GET", "**/api/v1/facility/**").as("createFacilities"); - cy.get("button#save-and-exit").click(); - cy.wait("@createFacilities").its("response.statusCode").should("eq", 200); + verifyFacilityUpdatedNotification() { + cy.verifyNotification("Facility updated successfully"); + cy.closeNotification(); } clickManageFacilityDropdown() { @@ -178,6 +85,10 @@ class FacilityPage { cy.get("#update-facility").contains("Update Facility").click(); } + clickUpdateFacilityButton() { + cy.verifyAndClickElement("#submit", "Update Facility"); + } + clickConfigureFacilityOption() { cy.get("#configure-facility").contains("Configure Facility").click(); } @@ -199,22 +110,6 @@ class FacilityPage { cy.get("#inventory-management").click(); } - getTotalBedCapacity() { - return cy.get("#total-bed-capacity"); - } - - getFacilityTotalBedCapacity() { - return cy.get("#facility-bed-capacity-details"); - } - - getFacilityTotalDoctorCapacity() { - return cy.get("#facility-doctor-capacity-details"); - } - - getTotalDoctorCapacity() { - return cy.get("#total-doctor-capacity"); - } - getFacilityName() { return cy.get("#facility-name"); } @@ -231,10 +126,6 @@ class FacilityPage { return cy.get("#facility-available-features"); } - getFacilityOxygenInfo() { - return cy.get("#facility-oxygen-info"); - } - clickResourceRequestOption() { cy.get("#resource-request").contains("Resource Request").click(); } @@ -243,64 +134,10 @@ class FacilityPage { cy.get("#delete-facility").contains("Delete Facility").click(); } - scrollToFacilityTriage() { - cy.get("#add-facility-triage").scrollIntoView(); - } - - fillTriageEntryFields( - visited: string, - homeQuarantine: string, - isolation: string, - referred: string, - confirmedPositive: string, - ) { - cy.get("#num_patients_visited").clear().click().type(visited); - cy.get("#num_patients_home_quarantine") - .clear() - .click() - .type(homeQuarantine); - cy.get("#num_patients_isolation").clear().click().type(isolation); - cy.get("#num_patient_referred").clear().click().type(referred); - cy.get("#num_patient_confirmed_positive") - .clear() - .click() - .type(confirmedPositive); - } - - fillEntryDate(date: string) { - cy.clickAndTypeDate("#entry_date", date); - } - - clickEditButton() { - cy.get("#edit-button").click(); - } - - clickButtonsMultipleTimes(selector: string) { - cy.get(selector).each(($button) => { - cy.wrap($button).click(); - }); - } - - verifyTriageTableContains(value: string) { - cy.get("#triage-table").contains(value); - } - - clickAddFacilityTriage() { - cy.get("#add-facility-triage").click(); - } - clickfacilityfeatureoption() { cy.get("#features").click(); } - clickbedcapcityaddmore() { - cy.get("#bed-capacity-save").click(); - } - - clickdoctorcapacityaddmore() { - cy.get("#doctor-save").click(); - } - clickcancelbutton() { cy.get("#cancel").click(); } @@ -509,30 +346,15 @@ class FacilityPage { // Fill location details this.fillLocationDetails(data.location); - // Fill oxygen details if provided - if (data.oxygen) { - this.fillOxygenDetails(data.oxygen); - } - - this.submitForm(); + this.clickSaveFacilityButton(); cy.closeNotification(); - // Add bed capacity if provided - if (data.beds) { - this.addBedCapacities(data.beds); - } - - // Add doctor capacity if provided - if (data.doctors) { - this.addDoctorCapacities(data.doctors); - } - this.verifyfacilitynewurl(); return this; } fillBasicDetails(basic: FacilityData["basic"]) { - this.fillFacilityName(basic.name); + this.typeFacilityName(basic.name); this.selectFacilityType(basic.type); if (basic.features?.length) { @@ -543,8 +365,8 @@ class FacilityPage { this.clickfacilityfeatureoption(); } - this.fillAddress(basic.address); - this.fillPhoneNumber(basic.phoneNumber); + this.typeFacilityAddress(basic.address); + this.typeFacilityPhoneNumber(basic.phoneNumber); if (basic.location) { this.selectLocation(basic.location); @@ -558,47 +380,6 @@ class FacilityPage { this.selectLocalBody(location.localBody); this.selectWard(location.ward); } - - fillOxygenDetails(oxygen: NonNullable) { - this.fillOxygenCapacity(oxygen.capacity); - this.fillExpectedOxygenRequirement(oxygen.expected); - - if (oxygen.bType) { - this.fillBTypeCylinderCapacity(oxygen.bType.capacity); - this.fillExpectedBTypeCylinderRequirement(oxygen.bType.expected); - } - - if (oxygen.cType) { - this.fillCTypeCylinderCapacity(oxygen.cType.capacity); - this.fillExpectedCTypeCylinderRequirement(oxygen.cType.expected); - } - - if (oxygen.dType) { - this.fillDTypeCylinderCapacity(oxygen.dType.capacity); - this.fillExpectedDTypeCylinderRequirement(oxygen.dType.expected); - } - } - - addBedCapacities(beds: NonNullable) { - beds.forEach((bed) => { - this.selectBedType(bed.type); - this.fillTotalCapacity(bed.totalCapacity); - this.fillCurrentlyOccupied(bed.occupied); - this.clickbedcapcityaddmore(); - cy.closeNotification(); - }); - this.clickcancelbutton(); - } - - addDoctorCapacities(doctors: NonNullable) { - doctors.forEach((doctor) => { - this.selectAreaOfSpecialization(doctor.specialization); - this.fillDoctorCount(doctor.count); - this.clickdoctorcapacityaddmore(); - cy.closeNotification(); - }); - this.clickcancelbutton(); - } } export default FacilityPage; diff --git a/cypress/pageobject/Facility/FacilityHome.ts b/cypress/pageobject/Facility/FacilityHome.ts index bbf5945453e..24f7d321628 100644 --- a/cypress/pageobject/Facility/FacilityHome.ts +++ b/cypress/pageobject/Facility/FacilityHome.ts @@ -1,7 +1,6 @@ class FacilityHome { // Selectors exportButton = "#export-button"; - menuItem = "[role='menuitem']"; // Operations clickExportButton() { @@ -10,7 +9,7 @@ class FacilityHome { } navigateToFacilityHomepage() { - cy.visit("/facility"); + cy.awaitUrl("/facility"); } assertFacilityInCard(facilityName: string) { @@ -29,10 +28,6 @@ class FacilityHome { cy.get("#facility-search").click().clear().type(facilityName); } - clickMenuItem(itemName: string) { - cy.get(this.menuItem).contains(itemName).click(); - } - csvDownloadIntercept(alias: string, queryParam: string) { cy.intercept("GET", `**/api/v1/facility/?csv${queryParam}`).as(alias); } diff --git a/cypress/pageobject/Facility/FacilityManage.ts b/cypress/pageobject/Facility/FacilityManage.ts index e7eecddab3c..00d9f642bbc 100644 --- a/cypress/pageobject/Facility/FacilityManage.ts +++ b/cypress/pageobject/Facility/FacilityManage.ts @@ -18,30 +18,6 @@ class FacilityManage { cy.get("#save-cover-image").click(); } - verifyTotalDoctorCapacity(expectedCapacity: string) { - cy.get("#facility-doctor-totalcapacity").contains(expectedCapacity); - } - - verifyFacilityBedCapacity(expectedCapacity: string) { - cy.get("#facility-bed-capacity-details").contains(expectedCapacity); - } - - clickEditFacilityDoctorCapacity() { - cy.get("#edit-facility-doctorcapacity").click(); - } - - clickEditFacilityBedCapacity() { - cy.get("#edit-facility-bedcapacity").click(); - } - - clickDeleteFacilityDoctorCapacity() { - cy.get("#delete-facility-doctorcapacity").click(); - } - - clickDeleteFacilityBedCapacity() { - cy.get("#delete-facility-bedcapacity").click(); - } - clickFacilityConfigureButton() { cy.get("#configure-facility").should("be.visible"); cy.get("#configure-facility").click(); @@ -90,16 +66,6 @@ class FacilityManage { cy.get("#hf_id").should("have.value", expectedValue); } - clickFacilityAddDoctorTypeButton() { - cy.get("#facility-add-doctortype").scrollIntoView(); - cy.get("#facility-add-doctortype").click(); - } - - clickFacilityAddBedTypeButton() { - cy.get("#facility-add-bedtype").scrollIntoView(); - cy.get("#facility-add-bedtype").click(); - } - visitViewPatients() { cy.intercept("GET", "**/api/v1/facility/**").as("getFacilityPatients"); cy.get("#view-patient-facility-list").scrollIntoView().click(); diff --git a/cypress/pageobject/Resource/ResourcePage.ts b/cypress/pageobject/Resource/ResourcePage.ts index 730d3dd9148..c01c60baec5 100644 --- a/cypress/pageobject/Resource/ResourcePage.ts +++ b/cypress/pageobject/Resource/ResourcePage.ts @@ -28,6 +28,10 @@ class ResourcePage { cy.contains("button", "Active").click(); } + navigationToResourcePage() { + cy.awaitUrl("/resource"); + } + verifyActiveResources() { cy.wait("@resource").its("response.statusCode").should("eq", 200); cy.contains("button", "Active").should("have.class", "text-white"); diff --git a/cypress/pageobject/utils/constants.ts b/cypress/pageobject/utils/constants.ts index 053d0561ce8..90baf3b6d4b 100644 --- a/cypress/pageobject/utils/constants.ts +++ b/cypress/pageobject/utils/constants.ts @@ -1,10 +1,122 @@ -export function generatePhoneNumber(): string { +function generatePhoneNumber(): string { const array = new Uint32Array(1); window.crypto.getRandomValues(array); const randomNum = (array[0] % 900000000) + 100000000; return "9" + randomNum.toString(); } -export function generateEmergencyPhoneNumber(): string { +function generateEmergencyPhoneNumber(): string { return generatePhoneNumber(); } + +function generateFacilityName(): string { + const prefixes = [ + "GHC", + "NHC", + "SHC", + "Apollo", + "General", + "St. Mary's", + "Central", + "Kochi", + ]; + const locations = [ + "North", + "South", + "East", + "West", + "Downtown", + "Metro", + "Springfield", + "Ernakulam", + ]; + const identifiers = [ + () => Math.floor(Math.random() * 100), // Numeric IDs + () => `Zone-${Math.floor(Math.random() * 10)}`, // Zone IDs + () => `Block-${String.fromCharCode(65 + Math.floor(Math.random() * 26))}`, // Alphabetic Blocks + ]; + const suffixes = [ + "Meta", + "Prime", + "Care", + "Wellness", + "Clinic", + "Center", + "Specialists", + "Hospital", + ]; + + const randomPrefix = prefixes[Math.floor(Math.random() * prefixes.length)]; + const randomLocation = + locations[Math.floor(Math.random() * locations.length)]; + const randomIdentifier = + identifiers[Math.floor(Math.random() * identifiers.length)](); + const randomSuffix = suffixes[Math.floor(Math.random() * suffixes.length)]; + + // Randomize the format of the name + const formats = [ + `${randomPrefix} ${randomLocation}-${randomIdentifier} ${randomSuffix}`, + `${randomLocation} ${randomPrefix} ${randomSuffix}`, + `${randomPrefix} ${randomLocation} ${randomSuffix}`, + ]; + + return formats[Math.floor(Math.random() * formats.length)]; +} + +function generateRandomAddress(multiline: boolean = false): string { + const localities = [ + "Marine Drive", + "Fort Kochi", + "Thevara", + "Vyttila", + "Edappally", + "Palarivattom", + "Kakkanad", + "Mattancherry", + "Kaloor", + "Tripunithura", + ]; + const neighborhoods = [ + "Lane 1", + "Lane 2", + "North Block", + "East End", + "West Side", + "Central Area", + "Market Road", + "Garden Street", + "Highland Avenue", + ]; + const districts = ["Kochi", "Ernakulam"]; + const states = ["Kerala"]; + const pincode = Math.floor(682000 + Math.random() * 1000).toString(); // Generate random pincodes in the 682XXX range. + + const randomLocality = + localities[Math.floor(Math.random() * localities.length)]; + const randomNeighborhood = + neighborhoods[Math.floor(Math.random() * neighborhoods.length)]; + const randomDistrict = + districts[Math.floor(Math.random() * districts.length)]; + const randomState = states[Math.floor(Math.random() * states.length)]; + + // Create address components + const addressParts = [ + randomNeighborhood, + randomLocality, + randomDistrict, + randomState, + `Pincode: ${pincode}`, + ]; + + // Return address as single line or multiline + // If 'multiline' is false, return address as a single line + // If 'multiline' is true, return address with each component on a new line + return multiline ? addressParts.join("\n") : addressParts.join(", "); +} + +export { + generatePhoneNumber, + generateEmergencyPhoneNumber, + generateFacilityName, + generateRandomAddress, +}; diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index 0268beebc42..f5bbcf42290 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -241,3 +241,21 @@ Cypress.Commands.add("verifyErrorMessages", (errorMessages: string[]) => { }); }); }); + +Cypress.Commands.add( + "typeIntoField", + ( + selector: string, + value: string, + options: { clearBeforeTyping?: boolean } = {}, + ) => { + const { clearBeforeTyping = false } = options; + const inputField = cy.get(selector); + + if (clearBeforeTyping) { + inputField.clear(); // Clear the input field + } + + inputField.click().type(value); // Click and type the new value + }, +); diff --git a/cypress/support/index.ts b/cypress/support/index.ts index 831ee71a5bc..fa01326698c 100644 --- a/cypress/support/index.ts +++ b/cypress/support/index.ts @@ -46,6 +46,11 @@ declare global { texts: string[], ): Chainable; verifyErrorMessages(errorMessages: string[]): Chainable; + typeIntoField( + selector: string, + value: string, + options?: { clearBeforeTyping?: boolean }, + ): Chainable; } } } diff --git a/package-lock.json b/package-lock.json index 41d7fcfff8c..6e57456063b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,7 +40,7 @@ "clsx": "^2.1.1", "cmdk": "^1.0.4", "cross-env": "^7.0.3", - "cypress": "^13.16.0", + "cypress": "^13.15.2", "dayjs": "^1.11.13", "echarts": "^5.5.1", "echarts-for-react": "^3.0.2", @@ -7807,9 +7807,9 @@ "license": "MIT" }, "node_modules/cypress": { - "version": "13.16.0", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.16.0.tgz", - "integrity": "sha512-g6XcwqnvzXrqiBQR/5gN+QsyRmKRhls1y5E42fyOvsmU7JuY+wM6uHJWj4ZPttjabzbnRvxcik2WemR8+xT6FA==", + "version": "13.15.2", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.15.2.tgz", + "integrity": "sha512-ARbnUorjcCM3XiPwgHKuqsyr5W9Qn+pIIBPaoilnoBkLdSC2oLQjV1BUpnmc7KR+b7Avah3Ly2RMFnfxr96E/A==", "hasInstallScript": true, "dependencies": { "@cypress/request": "^3.0.6", diff --git a/package.json b/package.json index 15392d09410..3db351e974b 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ "clsx": "^2.1.1", "cmdk": "^1.0.4", "cross-env": "^7.0.3", - "cypress": "^13.16.0", + "cypress": "^13.15.2", "dayjs": "^1.11.13", "echarts": "^5.5.1", "echarts-for-react": "^3.0.2", diff --git a/src/Routers/routes/FacilityRoutes.tsx b/src/Routers/routes/FacilityRoutes.tsx index 8c942518996..bf5d67ca67c 100644 --- a/src/Routers/routes/FacilityRoutes.tsx +++ b/src/Routers/routes/FacilityRoutes.tsx @@ -5,7 +5,6 @@ import { FacilityCreate } from "@/components/Facility/FacilityCreate"; import { FacilityHome } from "@/components/Facility/FacilityHome"; import { FacilityList } from "@/components/Facility/FacilityList"; import FacilityUsers from "@/components/Facility/FacilityUsers"; -import { TriageForm } from "@/components/Facility/TriageForm"; import ResourceCreate from "@/components/Resource/ResourceCreate"; import { AppRoutes } from "@/Routers/AppRouter"; @@ -36,12 +35,6 @@ const FacilityRoutes: AppRoutes = { "/facility/:facilityId/resource/new": ({ facilityId }) => ( ), - "/facility/:facilityId/triage": ({ facilityId }) => ( - - ), - "/facility/:facilityId/triage/:id": ({ facilityId, id }) => ( - - ), ...FacilityLocationRoutes, ...FacilityInventoryRoutes, }; diff --git a/src/Utils/request/api.tsx b/src/Utils/request/api.tsx index e7df6312c84..86886291f11 100644 --- a/src/Utils/request/api.tsx +++ b/src/Utils/request/api.tsx @@ -10,11 +10,6 @@ import { PatientAssetBed, } from "@/components/Assets/AssetTypes"; import { ICD11DiagnosisModel } from "@/components/Diagnosis/types"; -import { - IDeleteBedCapacity, - ILocalBodies, - ILocalBodyByDistrict, -} from "@/components/ExternalResult/models"; import { EventGeneric, type Type, @@ -27,7 +22,6 @@ import { Investigation } from "@/components/Facility/Investigations/Reports/type import { InvestigationSessionType } from "@/components/Facility/Investigations/investigationsTab"; import { BedModel, - CapacityModal, CommentModel, ConsultationModel, CreateBedBody, @@ -35,7 +29,6 @@ import { DailyRoundsBody, DailyRoundsRes, DistrictModel, - DoctorModal, FacilityModel, FacilityRequest, FacilitySpokeModel, @@ -51,7 +44,6 @@ import { MinimumQuantityItemResponse, PatientNotesEditModel, PatientNotesModel, - PatientStatsModel, PatientTransferResponse, ResourceModel, ShiftingModel, @@ -530,23 +522,6 @@ const routes = { method: "GET", TRes: Type(), }, - downloadFacilityCapacity: { - path: "/api/v1/facility/?csv&capacity", - method: "GET", - TRes: Type(), - }, - downloadFacilityDoctors: { - path: "/api/v1/facility/?csv&doctors", - method: "GET", - TRes: Type(), - }, - - downloadFacilityTriage: { - path: "/api/v1/facility/?csv&triage", - method: "GET", - TRes: Type(), - }, - downloadPatients: { path: "/api/v1/patient/?csv", method: "GET", @@ -634,86 +609,6 @@ const routes = { TRes: Type>(), }, - // Hospital Beds - createCapacity: { - path: "/api/v1/facility/{facilityId}/capacity/", - method: "POST", - TRes: Type(), - }, - - createDoctor: { - path: "/api/v1/facility/{facilityId}/hospital_doctor/", - method: "POST", - TRes: Type(), - TBody: Type(), - }, - - getCapacity: { - path: "/api/v1/facility/{facilityId}/capacity/", - TRes: Type>(), - }, - - getCapacityBed: { - path: "/api/v1/facility/{facilityId}/capacity/{bed_id}/", - TRes: Type(), - }, - - deleteCapacityBed: { - path: "/api/v1/facility/{facilityId}/capacity/{bed_id}/", - method: "DELETE", - TRes: Type(), - }, - - listDoctor: { - path: "/api/v1/facility/{facilityId}/hospital_doctor/", - TRes: Type>(), - }, - getDoctor: { - path: "/api/v1/facility/{facilityId}/hospital_doctor/{id}/", - TRes: Type(), - }, - - updateCapacity: { - path: "/api/v1/facility/{facilityId}/capacity/{bed_id}/", - method: "PUT", - TRes: Type(), - }, - - updateDoctor: { - path: "/api/v1/facility/{facilityId}/hospital_doctor/{id}/", - method: "PUT", - TRes: Type(), - }, - - deleteDoctor: { - path: "/api/v1/facility/{facilityId}/hospital_doctor/{area}/", - method: "DELETE", - TRes: Type>(), - }, - - //Triage - createTriage: { - path: "/api/v1/facility/{facilityId}/patient_stats/", - method: "POST", - TBody: Type(), - TRes: Type(), - }, - getTriage: { - path: "/api/v1/facility/{facilityId}/patient_stats/", - TRes: Type>(), - }, - - getTriageDetails: { - path: "/api/v1/facility/{facilityId}/patient_stats/{id}/", - TRes: Type(), - }, - - // //Care Center - // createCenter: { - // path: "/api/v1/carecenter/", - // method: 'POST' - // } - // Patient searchPatient: { @@ -813,12 +708,12 @@ const routes = { getAllLocalBodyByDistrict: { path: "/api/v1/district/{id}/get_all_local_body/", method: "GET", - TRes: Type(), + TRes: Type(), }, getLocalbodyByDistrict: { path: "/api/v1/district/{id}/local_bodies/", method: "GET", - TRes: Type(), + TRes: Type(), }, // Local Body diff --git a/src/components/ExternalResult/models.ts b/src/components/ExternalResult/models.ts deleted file mode 100644 index bc5f8d29e03..00000000000 --- a/src/components/ExternalResult/models.ts +++ /dev/null @@ -1,18 +0,0 @@ -export interface ILocalBodies { - id: number; - name: string; - state: number; - number: number; - body_type: number; - localbody_code: string; - district: number; -} -export interface IDeleteBedCapacity { - detail: string; -} - -export interface ILocalBodyByDistrict { - id: number; - name: string; - state: number; -} diff --git a/src/components/Facility/BedCapacity.tsx b/src/components/Facility/BedCapacity.tsx deleted file mode 100644 index 156dc6adce6..00000000000 --- a/src/components/Facility/BedCapacity.tsx +++ /dev/null @@ -1,301 +0,0 @@ -import { useEffect, useReducer, useState } from "react"; -import { useTranslation } from "react-i18next"; - -import { Cancel, Submit } from "@/components/Common/ButtonV2"; -import { CapacityModal, OptionsType } from "@/components/Facility/models"; -import { SelectFormField } from "@/components/Form/FormFields/SelectFormField"; -import TextFormField from "@/components/Form/FormFields/TextFormField"; -import { FieldChangeEvent } from "@/components/Form/FormFields/Utils"; - -import { BED_TYPES } from "@/common/constants"; - -import * as Notification from "@/Utils/Notifications"; -import routes from "@/Utils/request/api"; -import request from "@/Utils/request/request"; - -interface BedCapacityProps extends CapacityModal { - facilityId: string; - handleClose: () => void; - handleUpdate: () => void; - className?: string; - id?: number; -} - -const initForm: any = { - bedType: "", - totalCapacity: "", - currentOccupancy: "", -}; - -const initialState = { - form: { ...initForm }, - errors: { ...initForm }, -}; - -const bedCountReducer = (state = initialState, action: any) => { - switch (action.type) { - case "set_form": { - return { - ...state, - form: action.form, - }; - } - case "set_error": { - return { - ...state, - errors: action.errors, - }; - } - default: - return state; - } -}; - -export const BedCapacity = (props: BedCapacityProps) => { - const { t } = useTranslation(); - const { facilityId, handleClose, handleUpdate, className, id } = props; - const [state, dispatch] = useReducer(bedCountReducer, initialState); - const [isLastOptionType, setIsLastOptionType] = useState(false); - const [bedTypes, setBedTypes] = useState( - BED_TYPES.map((o) => ({ id: o, text: t(`bed_type__${o}`) })), - ); - const [isLoading, setIsLoading] = useState(false); - - const headerText = !id ? "Add Bed Capacity" : "Edit Bed Capacity"; - const buttonText = !id - ? `Save ${!isLastOptionType ? "& Add More" : "Bed Capacity"}` - : "Update Bed Capacity"; - - async function fetchCapacityBed() { - setIsLoading(true); - if (!id) { - // Add Form functionality - const capacityQuery = await request(routes.getCapacity, { - pathParams: { facilityId: props.facilityId }, - }); - if (capacityQuery?.data) { - const existingData = capacityQuery.data?.results; - // if all options are diabled - if (existingData.length === BED_TYPES.length) { - setBedTypes([]); - setIsLoading(false); - return; - } - // disable existing bed types - const updatedBedTypes = BED_TYPES.map((type) => { - const isExisting = existingData.find( - (i: CapacityModal) => i.room_type === type, - ); - return { - id: type, - text: t(`bed_type__${type}`), - disabled: !!isExisting, - }; - }); - setBedTypes(updatedBedTypes); - } - } else { - // Edit Form functionality - const capacityQuery = await request(routes.getCapacityBed, { - pathParams: { facilityId: props.facilityId, bed_id: id.toString() }, - }); - if (capacityQuery.data) { - dispatch({ - type: "set_form", - form: { - bedType: capacityQuery.data.room_type, - totalCapacity: capacityQuery.data.total_capacity, - currentOccupancy: capacityQuery.data.current_capacity, - }, - }); - } - } - setIsLoading(false); - } - - useEffect(() => { - fetchCapacityBed(); - }, []); - - useEffect(() => { - const lastBedType = - bedTypes.filter((i: OptionsType) => i.disabled).length === - BED_TYPES.length - 1; - setIsLastOptionType(lastBedType); - }, [bedTypes]); - - const handleChange = (e: FieldChangeEvent) => { - const form = { ...state.form }; - form[e.name] = e.value; - dispatch({ type: "set_form", form }); - }; - - const validateData = () => { - const errors = { ...initForm }; - let invalidForm = false; - Object.keys(state.form).forEach((field) => { - if (!state.form[field]) { - errors[field] = t("field_required"); - invalidForm = true; - } else if ( - field === "currentOccupancy" && - Number(state.form[field] < 0) - ) { - errors[field] = "Occupied cannot be negative"; - invalidForm = true; - } else if ( - field === "currentOccupancy" && - Number(state.form[field]) > Number(state.form.totalCapacity) - ) { - errors[field] = "Occupied must be less than or equal to total capacity"; - invalidForm = true; - } - if (field === "totalCapacity" && Number(state.form[field]) === 0) { - errors[field] = "Total capacity cannot be 0"; - invalidForm = true; - } else if (field === "totalCapacity" && Number(state.form[field]) < 0) { - errors[field] = "Total capacity cannot be negative"; - invalidForm = true; - } - }); - if (invalidForm) { - dispatch({ type: "set_error", errors }); - return false; - } - dispatch({ type: "set_error", errors }); - return true; - }; - - const handleSubmit = async (e: any, btnType = "Save") => { - e.preventDefault(); - const valid = validateData(); - if (valid) { - setIsLoading(true); - const bodyData = { - room_type: Number(state.form.bedType), - total_capacity: Number(state.form.totalCapacity), - current_capacity: Number(state.form.currentOccupancy), - }; - const { data } = await request( - id ? routes.updateCapacity : routes.createCapacity, - { - pathParams: { facilityId, ...(id ? { bed_id: id.toString() } : {}) }, - body: bodyData, - }, - ); - setIsLoading(false); - if (data) { - const updatedBedTypes = bedTypes.map((type) => { - return { - ...type, - disabled: data.room_type !== type.id ? type.disabled : true, - }; - }); - setBedTypes(updatedBedTypes); - // reset form - dispatch({ type: "set_form", form: initForm }); - // show success message - if (!id) { - Notification.Success({ - msg: "Bed capacity added successfully", - }); - } else { - Notification.Success({ - msg: "Bed capacity updated successfully", - }); - } - handleUpdate(); - } - if (btnType == "Save and Exit") handleClose(); - } - }; - - return ( -
    - {isLoading ? ( -
    -
    - - Loading... -
    -
    - ) : ( -
    - !type.disabled)} - optionLabel={(option) => option.text} - optionValue={(option) => option.id} - onChange={handleChange} - disabled={!!id} - error={state.errors.bedType} - /> -
    - - -
    - -
    - - {headerText === "Add Bed Capacity" && ( - handleSubmit(e, "Save and Exit")} - label="Save Bed Capacity" - /> - )} - {!isLastOptionType && ( - handleSubmit(e)} - label={buttonText} - /> - )} -
    -
    - )} -
    - ); -}; diff --git a/src/components/Facility/BedTypeCard.tsx b/src/components/Facility/BedTypeCard.tsx deleted file mode 100644 index 99244bd7eb1..00000000000 --- a/src/components/Facility/BedTypeCard.tsx +++ /dev/null @@ -1,181 +0,0 @@ -import { useEffect, useState } from "react"; - -import RecordMeta from "@/CAREUI/display/RecordMeta"; -import CareIcon from "@/CAREUI/icons/CareIcon"; - -import ButtonV2 from "@/components/Common/ButtonV2"; -import ConfirmDialog from "@/components/Common/ConfirmDialog"; -import DialogModal from "@/components/Common/Dialog"; -import { BedCapacity } from "@/components/Facility/BedCapacity"; - -import { NonReadOnlyUsers } from "@/Utils/AuthorizeFor"; -import * as Notification from "@/Utils/Notifications"; -import routes from "@/Utils/request/api"; -import request from "@/Utils/request/request"; - -interface BedTypeCardProps { - facilityId?: string; - bedCapacityId?: number; - room_type?: number; - label: string; - used: number; - total: number; - lastUpdated?: string; - removeBedType?: (bedTypeId: number | undefined) => void; - handleUpdate: () => void; -} - -export const BedTypeCard: React.FC = ({ - facilityId, - bedCapacityId, - room_type, - label, - used, - total, - lastUpdated, - removeBedType, - handleUpdate, -}) => { - const [isRefreshing, setIsRefreshing] = useState(false); - const [openDeleteDialog, setOpenDeleteDialog] = useState(false); - const [open, setOpen] = useState(false); - const [selectedId, setSelectedId] = useState(-1); - const handleDeleteSubmit = async () => { - if (room_type) { - const { res } = await request(routes.deleteCapacityBed, { - pathParams: { - facilityId: facilityId ?? "", - bed_id: room_type.toString(), - }, - }); - if (res?.status == 204) { - Notification.Success({ - msg: "Bed type deleted successfully", - }); - setOpenDeleteDialog(false); - if (removeBedType) { - removeBedType(bedCapacityId); - } - } - } - }; - - useEffect(() => { - if (isRefreshing) { - setTimeout(() => { - setIsRefreshing(false); - }, 500); - } - }, [isRefreshing]); - - const usedPercent = total ? Math.round((used / total) * 100) : 0; - - return ( -
    -
    -
    - {label} -
    - - {usedPercent}% - -
    -
    - {used} / {total} -
    -
    -
    -
    -
    - -
    - {" "} - Currently Occupied / Total Capacity{" "} -
    - {facilityId ? ( -
    -
    - {lastUpdated && ( - - )} -
    -
    - { - setSelectedId(room_type || 0); - setOpen(true); - }} - authorizeFor={NonReadOnlyUsers} - className="tooltip bg-opacity/20 flex aspect-square h-7 w-7 flex-col items-center justify-center rounded bg-secondary-300 px-4 py-0" - variant="secondary" - ghost - > - - Edit - - - setOpenDeleteDialog(true)} - authorizeFor={NonReadOnlyUsers} - className="tooltip bg-opacity/10 flex aspect-square h-7 w-7 flex-col items-center justify-center rounded bg-red-100 px-4 py-0 hover:bg-red-200" - variant="secondary" - ghost - > - - Delete - -
    -
    - ) : ( -
    - )} -
    - setOpenDeleteDialog(false)} - title={`Delete ${label}?`} - description="You will not be able to access this bed type later." - action="Delete" - variant="danger" - onConfirm={handleDeleteSubmit} - /> - {open && ( - setOpen(false)} - title="Update Bed Capacity" - className="max-w-lg md:min-w-[650px]" - > - { - setOpen(false); - }} - handleUpdate={() => { - handleUpdate(); - setOpen(false); - }} - id={selectedId} - /> - - )} -
    - ); -}; - -export default BedTypeCard; diff --git a/src/components/Facility/FacilityBedCapacity.tsx b/src/components/Facility/FacilityBedCapacity.tsx deleted file mode 100644 index cf0ac28a24a..00000000000 --- a/src/components/Facility/FacilityBedCapacity.tsx +++ /dev/null @@ -1,126 +0,0 @@ -import { useState } from "react"; -import { useTranslation } from "react-i18next"; - -import CareIcon from "@/CAREUI/icons/CareIcon"; - -import ButtonV2 from "@/components/Common/ButtonV2"; -import DialogModal from "@/components/Common/Dialog"; -import { BedCapacity } from "@/components/Facility/BedCapacity"; -import BedTypeCard from "@/components/Facility/BedTypeCard"; - -import { BED_TYPES } from "@/common/constants"; - -import { NonReadOnlyUsers } from "@/Utils/AuthorizeFor"; -import routes from "@/Utils/request/api"; -import useTanStackQueryInstead from "@/Utils/request/useQuery"; - -export const FacilityBedCapacity = (props: any) => { - const { t } = useTranslation(); - - const [bedCapacityModalOpen, setBedCapacityModalOpen] = useState(false); - - const capacityQuery = useTanStackQueryInstead(routes.getCapacity, { - pathParams: { facilityId: props.facilityId }, - }); - - let capacityList: any = null; - if (!capacityQuery.data || !capacityQuery.data.results.length) { - capacityList = ( -
    - No Bed Types Found -
    - ); - } else { - const totalBedCount = capacityQuery.data.results.reduce( - (acc, x) => acc + (x.total_capacity ? x.total_capacity : 0), - 0, - ); - const totalOccupiedBedCount = capacityQuery.data.results.reduce( - (acc, x) => acc + (x.current_capacity ? x.current_capacity : 0), - 0, - ); - - capacityList = ( -
    - { - return; - }} - /> - {BED_TYPES.map((x) => { - const res = capacityQuery.data?.results.find((data) => { - return data.room_type === x; - }); - if ( - res && - res.current_capacity !== undefined && - res.total_capacity !== undefined - ) { - const removeCurrentBedType = (bedTypeId: number | undefined) => { - if (capacityQuery.data !== undefined) { - capacityQuery.data.results.filter((i) => i.id !== bedTypeId); - capacityQuery.refetch(); - } - }; - return ( - { - capacityQuery.refetch(); - }} - /> - ); - } - })} -
    - ); - } - - return ( -
    -
    -
    -
    Bed Capacity
    - setBedCapacityModalOpen(true)} - authorizeFor={NonReadOnlyUsers} - > - - Add More Bed Types - -
    -
    {capacityList}
    -
    - - {bedCapacityModalOpen && ( - setBedCapacityModalOpen(false)} - title="Add Bed Capacity" - className="max-w-md md:min-w-[600px]" - > - setBedCapacityModalOpen(false)} - handleUpdate={async () => { - capacityQuery.refetch(); - }} - /> - - )} -
    - ); -}; diff --git a/src/components/Facility/FacilityCreate.tsx b/src/components/Facility/FacilityCreate.tsx index 37b98492c6f..84af22aabee 100644 --- a/src/components/Facility/FacilityCreate.tsx +++ b/src/components/Facility/FacilityCreate.tsx @@ -16,18 +16,8 @@ import ButtonV2, { Cancel, Submit } from "@/components/Common/ButtonV2"; import GLocationPicker from "@/components/Common/GLocationPicker"; import Loading from "@/components/Common/Loading"; import Page from "@/components/Common/Page"; -import Steps, { Step } from "@/components/Common/Steps"; -import { BedCapacity } from "@/components/Facility/BedCapacity"; -import BedTypeCard from "@/components/Facility/BedTypeCard"; import SpokeFacilityEditor from "@/components/Facility/SpokeFacilityEditor"; -import { StaffCapacity } from "@/components/Facility/StaffCapacity"; -import StaffCountCard from "@/components/Facility/StaffCountCard"; -import { - CapacityModal, - DistrictModel, - DoctorModal, - FacilityRequest, -} from "@/components/Facility/models"; +import { DistrictModel, FacilityRequest } from "@/components/Facility/models"; import { PhoneNumberValidator } from "@/components/Form/FieldValidators"; import PhoneNumberFormField from "@/components/Form/FormFields/PhoneNumberFormField"; import RadioFormField from "@/components/Form/FormFields/RadioFormField"; @@ -43,11 +33,7 @@ import { FormAction } from "@/components/Form/Utils"; import useAppHistory from "@/hooks/useAppHistory"; import useAuthUser from "@/hooks/useAuthUser"; -import { - BED_TYPES, - FACILITY_FEATURE_TYPES, - FACILITY_TYPES, -} from "@/common/constants"; +import { FACILITY_FEATURE_TYPES, FACILITY_TYPES } from "@/common/constants"; import { phonePreg, validateLatitude, @@ -86,14 +72,6 @@ type FacilityForm = { latitude: string; longitude: string; pincode: string; - oxygen_capacity?: number; - type_b_cylinders?: number; - type_c_cylinders?: number; - type_d_cylinders?: number; - expected_oxygen_requirement?: number; - expected_type_b_cylinders?: number; - expected_type_c_cylinders?: number; - expected_type_d_cylinders?: number; }; const initForm: FacilityForm = { @@ -110,14 +88,6 @@ const initForm: FacilityForm = { latitude: "", longitude: "", pincode: "", - oxygen_capacity: undefined, - type_b_cylinders: undefined, - type_c_cylinders: undefined, - type_d_cylinders: undefined, - expected_oxygen_requirement: undefined, - expected_type_b_cylinders: undefined, - expected_type_c_cylinders: undefined, - expected_type_d_cylinders: undefined, }; const initError: Record = Object.assign( @@ -152,13 +122,8 @@ export const FacilityCreate = (props: FacilityProps) => { initialState, ); const [isLoading, setIsLoading] = useState(false); - const [currentStep, setCurrentStep] = useState(1); - const [createdFacilityId, setCreatedFacilityId] = useState(""); + const [showAutoFilledPincode, setShowAutoFilledPincode] = useState(false); - const [capacityData, setCapacityData] = useState>([]); - const [doctorData, setDoctorData] = useState>([]); - const [bedCapacityKey, setBedCapacityKey] = useState(0); - const [docCapacityKey, setDocCapacityKey] = useState(0); const [stateId, setStateId] = useState(); const [districtId, setDistrictId] = useState(); const [localBodyId, setLocalBodyId] = useState(); @@ -200,43 +165,6 @@ export const FacilityCreate = (props: FacilityProps) => { prefetch: !!districtId, }); - const getSteps = (): Step[] => { - return [ - { - id: 1, - name: "Facility details", - onClick: () => { - setCurrentStep(1); - }, - status: currentStep === 1 ? "current" : "complete", - disabled: currentStep > 1, - }, - { - id: 2, - name: "Bed Capacity", - onClick: () => { - setCurrentStep(2); - }, - status: - currentStep === 2 - ? "current" - : currentStep > 2 - ? "complete" - : "upcoming", - disabled: createdFacilityId == "", - }, - { - id: 3, - name: "Staff Capacity", - onClick: () => { - setCurrentStep(3); - }, - disabled: createdFacilityId == "", - status: currentStep === 3 ? "current" : "upcoming", - }, - ]; - }; - const { data: wardData, loading: isWardLoading } = useTanStackQueryInstead( routes.getWardByLocalBody, { @@ -276,14 +204,6 @@ export const FacilityCreate = (props: FacilityProps) => { longitude: data.longitude ? parseFloat(data.longitude).toFixed(7) : "", - type_b_cylinders: data.type_b_cylinders, - type_c_cylinders: data.type_c_cylinders, - type_d_cylinders: data.type_d_cylinders, - expected_type_b_cylinders: data.expected_type_b_cylinders, - expected_type_c_cylinders: data.expected_type_c_cylinders, - expected_type_d_cylinders: data.expected_type_d_cylinders, - expected_oxygen_requirement: data.expected_oxygen_requirement, - oxygen_capacity: data.oxygen_capacity, }; dispatch({ type: "set_form", form: formData }); setStateId(data.state); @@ -469,32 +389,6 @@ export const FacilityCreate = (props: FacilityProps) => { latitude: state.form.latitude, longitude: state.form.longitude, phone_number: parsePhoneNumber(state.form.phone_number), - oxygen_capacity: state.form.oxygen_capacity - ? state.form.oxygen_capacity - : 0, - type_b_cylinders: state.form.type_b_cylinders - ? state.form.type_b_cylinders - : 0, - type_c_cylinders: state.form.type_c_cylinders - ? state.form.type_c_cylinders - : 0, - type_d_cylinders: state.form.type_d_cylinders - ? state.form.type_d_cylinders - : 0, - expected_oxygen_requirement: state.form.expected_oxygen_requirement - ? state.form.expected_oxygen_requirement - : 0, - expected_type_b_cylinders: state.form.expected_type_b_cylinders - ? state.form.expected_type_b_cylinders - : 0, - - expected_type_c_cylinders: state.form.expected_type_c_cylinders - ? state.form.expected_type_c_cylinders - : 0, - - expected_type_d_cylinders: state.form.expected_type_d_cylinders - ? state.form.expected_type_d_cylinders - : 0, }; const { res, data: requestData } = facilityId @@ -515,14 +409,12 @@ export const FacilityCreate = (props: FacilityProps) => { Notification.Success({ msg: "Facility added successfully", }); - setCreatedFacilityId(String(id)); - setCurrentStep(2); } else { Notification.Success({ msg: "Facility updated successfully", }); - navigate(`/facility/${facilityId}`); } + navigate(`/facility/${id}`); } setIsLoading(false); } @@ -532,112 +424,6 @@ export const FacilityCreate = (props: FacilityProps) => { return ; } - let capacityList: any = null; - let totalBedCount = 0; - let totalOccupiedBedCount = 0; - - if (!capacityData || !capacityData.length) { - capacityList = ( -
    - {t("no_bed_types_found")} -
    - ); - } else { - capacityData.forEach((x) => { - totalBedCount += x.total_capacity ? x.total_capacity : 0; - totalOccupiedBedCount += x.current_capacity ? x.current_capacity : 0; - }); - - capacityList = ( -
    - { - return; - }} - /> - {BED_TYPES.map((x) => { - const res = capacityData.find((data) => { - return data.room_type === x; - }); - if (res) { - const removeCurrentBedType = (bedTypeId: number | undefined) => { - setCapacityData((state) => - state.filter((i) => i.id !== bedTypeId), - ); - setBedCapacityKey((bedCapacityKey) => bedCapacityKey + 1); - }; - return ( - { - const { res, data } = await request(routes.getCapacity, { - pathParams: { facilityId: createdFacilityId }, - }); - if (res?.ok && data) { - setCapacityData(data.results); - } - }} - /> - ); - } - })} -
    - ); - } - let doctorList: any = null; - if (!doctorData || !doctorData.length) { - doctorList = ( -
    - {t("no_staff")} -
    - ); - } else { - doctorList = ( -
    - {doctorData.map((data: DoctorModal) => { - const removeCurrentDoctorData = (doctorId: number | undefined) => { - setDoctorData((state) => - state.filter((i: DoctorModal) => i.id !== doctorId), - ); - setDocCapacityKey((docCapacityKey) => docCapacityKey + 1); - }; - - return ( - { - const { res, data } = await request(routes.listDoctor, { - pathParams: { facilityId: createdFacilityId }, - }); - if (res?.ok && data) { - setDoctorData(data.results); - } - }} - {...data} - removeDoctor={removeCurrentDoctorData} - /> - ); - })} -
    - ); - } - const field = (name: string) => { return { name, @@ -649,370 +435,210 @@ export const FacilityCreate = (props: FacilityProps) => { }; }; - switch (currentStep) { - case 3: - return ( - - -
    - { - navigate(`/facility/${createdFacilityId}`); - }} - handleUpdate={async () => { - const { res, data } = await request(routes.listDoctor, { - pathParams: { facilityId: createdFacilityId }, - }); - if (res?.ok && data) { - setDoctorData(data.results); - } + return ( + + +
    +
    handleSubmit(e)}> + { + dispatch({ type: "set_state", state: newState }); + setStateId(newState.form.state); + setDistrictId(newState.form.district); + setLocalBodyId(newState.form.local_body); }} + formData={state.form} /> -
    -
    -
    -
    {t("staff_list")}
    -
    -
    - {doctorList} -
    -
    -
    - ); - case 2: - return ( - - -
    - { - setCurrentStep(3); - }} - handleUpdate={async () => { - const { res, data } = await request(routes.getCapacity, { - pathParams: { facilityId: createdFacilityId }, - }); - if (res?.ok && data) { - setCapacityData(data.results); - } - }} - /> -
    -
    -
    -
    - {t("bed_capacity")} -
    -
    -
    {capacityList}
    -
    -
    - ); - case 1: - default: - return ( - - {!facilityId && } - -
    - handleSubmit(e)}> - { - dispatch({ type: "set_state", state: newState }); - setStateId(newState.form.state); - setDistrictId(newState.form.district); - setLocalBodyId(newState.form.local_body); - }} - formData={state.form} +
    + o.text} + optionValue={(o) => o.text} + /> + + o.name} + optionValue={(o) => o.id} + /> +
    + -
    - o.text} - optionValue={(o) => o.text} - /> - - o.name} - optionValue={(o) => o.id} - /> -
    - - {showAutoFilledPincode && ( -
    - - - State and district auto-filled from pincode - -
    - )} + {showAutoFilledPincode && ( +
    + + + State and district auto-filled from pincode +
    - o.name} - optionValue={(o) => o.id} - onChange={(event) => { - handleChange(event); - if (!event) return; - setStateId(event.value); - }} - /> - o.name} - optionValue={(o) => o.id} - onChange={(event) => { - handleChange(event); - if (!event) return; - setDistrictId(event.value); - }} - /> - o.name} - optionValue={(o) => o.id} - onChange={(event) => { - handleChange(event); - if (!event) return; - setLocalBodyId(event.value); - }} - /> - { - return { - id: e.id, - name: e.number + ": " + e.name, - }; - })} - optionLabel={(o) => o.name} - optionValue={(o) => o.id} - /> - - + o.name} + optionValue={(o) => o.id} + onChange={(event) => { + handleChange(event); + if (!event) return; + setStateId(event.value); + }} + /> + o.name} + optionValue={(o) => o.id} + onChange={(event) => { + handleChange(event); + if (!event) return; + setDistrictId(event.value); + }} + /> + o.name} + optionValue={(o) => o.id} + onChange={(event) => { + handleChange(event); + if (!event) return; + setLocalBodyId(event.value); + }} + /> + { + return { + id: e.id, + name: e.number + ": " + e.name, + }; + })} + optionLabel={(o) => o.name} + optionValue={(o) => o.id} + /> + + + {facilityId && ( +
    +

    {t("spokes")}

    + - {facilityId && ( -
    -

    {t("spokes")}

    - -
    - )} -
    - } - min={0} - /> - } - label={t("expected_burn_rate")} - min={0} - /> - - } - min={0} - /> - } - min={0} - /> - } - min={0} - /> - } - label={t("expected_burn_rate")} - min={0} - /> - } - min={0} - /> - } - min={0} - /> -
    - - {careConfig.kasp.enabled && ( - (o ? "Yes" : "No")} - optionValue={(o) => String(o)} - /> - )}
    + )} + {careConfig.kasp.enabled && ( + (o ? "Yes" : "No")} + optionValue={(o) => String(o)} + /> + )} +
    -
    - +
    + -
    - - <> - - - - - Select location from map - - - - - - - null} - handleOnSelectCurrentLocation={ - handleSelectCurrentLocation - } - /> - - - - -
    - } - placeholder="Longitude" - /> -
    -
    - goBack()} /> - -
    - +
    + + <> + + + + + Select location from map + + + + + + + null} + handleOnSelectCurrentLocation={ + handleSelectCurrentLocation + } + /> + + + + +
    + } + placeholder="Longitude" + />
    - - - ); - } -}; - -const FieldUnit = ({ unit }: { unit: string }) => { - return

    {unit}

    ; +
    + goBack()} /> + +
    + +
    + + + ); }; diff --git a/src/components/Facility/FacilityHome.tsx b/src/components/Facility/FacilityHome.tsx index cf671a51530..1808a1087ee 100644 --- a/src/components/Facility/FacilityHome.tsx +++ b/src/components/Facility/FacilityHome.tsx @@ -22,11 +22,7 @@ import Loading from "@/components/Common/Loading"; import { LocationSelect } from "@/components/Common/LocationSelect"; import DropdownMenu, { DropdownItem } from "@/components/Common/Menu"; import Page from "@/components/Common/Page"; -import Table from "@/components/Common/Table"; -import { FacilityBedCapacity } from "@/components/Facility/FacilityBedCapacity"; import FacilityBlock from "@/components/Facility/FacilityBlock"; -import { FacilityHomeTriage } from "@/components/Facility/FacilityHomeTriage"; -import { FacilityStaffList } from "@/components/Facility/FacilityStaffList"; import { FieldLabel } from "@/components/Form/FormFields/FormField"; import useAuthUser from "@/hooks/useAuthUser"; @@ -215,7 +211,10 @@ export const FacilityHome = ({ facilityId }: Props) => { onClick={() => setEditCoverImage(true)} className="md:mr-2 lg:mr-6 lg:h-80 lg:w-80" /> -
    +

    @@ -488,44 +487,6 @@ export const FacilityHome = ({ facilityId }: Props) => {

    - - - -
    -

    {t("oxygen_information")}

    -
    -
    - - - - ); }; diff --git a/src/components/Facility/FacilityHomeTriage.tsx b/src/components/Facility/FacilityHomeTriage.tsx deleted file mode 100644 index 25d2e0a7334..00000000000 --- a/src/components/Facility/FacilityHomeTriage.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import { navigate } from "raviger"; - -import CareIcon from "@/CAREUI/icons/CareIcon"; - -import ButtonV2 from "@/components/Common/ButtonV2"; -import Table from "@/components/Common/Table"; - -import { NonReadOnlyUsers } from "@/Utils/AuthorizeFor"; -import routes from "@/Utils/request/api"; -import useTanStackQueryInstead from "@/Utils/request/useQuery"; - -interface FacilityHomeTriageProps { - facilityId: string; -} - -export function FacilityHomeTriage({ facilityId }: FacilityHomeTriageProps) { - const { data } = useTanStackQueryInstead(routes.getTriage, { - pathParams: { facilityId }, - }); - - const tableRows = - data?.results?.map((result) => [ - String(result.entry_date), - String(result.num_patients_visited), - String(result.num_patients_home_quarantine), - String(result.num_patients_isolation), - String(result.num_patient_referred), - String(result.num_patient_confirmed_positive), - navigate(`/facility/${facilityId}/triage/${result.id}`)} - authorizeFor={NonReadOnlyUsers} - > - Edit - , - ]) ?? []; - - const tableHeadings = [ - "Date", - "Total Triaged", - "Advised Home Quarantine", - "Suspects Isolated", - "Referred", - "Confirmed positives", - "Actions", - ]; - - return ( -
    -
    -
    -
    Corona Triage
    - navigate(`/facility/${facilityId}/triage`)} - authorizeFor={NonReadOnlyUsers} - > - - Add Triage - -
    - -
    -
    - - {tableRows.length === 0 && ( - <> -
    -
    - No Data Found -
    - - )} - - - - ); -} diff --git a/src/components/Facility/FacilityList.tsx b/src/components/Facility/FacilityList.tsx index 0c1164649ca..f62f630dcaa 100644 --- a/src/components/Facility/FacilityList.tsx +++ b/src/components/Facility/FacilityList.tsx @@ -157,30 +157,17 @@ export const FacilityList = () => { options={
    advancedFilter.setShow(true)} /> - +
    + +
    } > diff --git a/src/components/Facility/FacilityStaffList.tsx b/src/components/Facility/FacilityStaffList.tsx deleted file mode 100644 index 5a3cd512ba9..00000000000 --- a/src/components/Facility/FacilityStaffList.tsx +++ /dev/null @@ -1,138 +0,0 @@ -import { useState } from "react"; -import { useTranslation } from "react-i18next"; - -import CareIcon from "@/CAREUI/icons/CareIcon"; - -import ButtonV2 from "@/components/Common/ButtonV2"; -import DialogModal from "@/components/Common/Dialog"; -import Pagination from "@/components/Common/Pagination"; -import { StaffCapacity } from "@/components/Facility/StaffCapacity"; -import DoctorsCountCard from "@/components/Facility/StaffCountCard"; -import { DoctorModal } from "@/components/Facility/models"; -import { DoctorIcon } from "@/components/TeleIcu/Icons/DoctorIcon"; - -import useFilters from "@/hooks/useFilters"; - -import { DOCTOR_SPECIALIZATION } from "@/common/constants"; - -import { NonReadOnlyUsers } from "@/Utils/AuthorizeFor"; -import routes from "@/Utils/request/api"; -import useTanStackQueryInstead from "@/Utils/request/useQuery"; - -export const FacilityStaffList = (props: any) => { - const { t } = useTranslation(); - const [doctorCapacityModalOpen, setDoctorCapacityModalOpen] = useState(false); - const { qParams, resultsPerPage, updatePage } = useFilters({ limit: 15 }); - const [totalDoctors, setTotalDoctors] = useState(0); - - const { data: doctorsList, refetch } = useTanStackQueryInstead( - routes.listDoctor, - { - pathParams: { facilityId: props.facilityId }, - query: { - limit: resultsPerPage, - offset: (qParams.page - 1) * resultsPerPage, - }, - onResponse: ({ res, data }) => { - if (res?.ok && data) { - let totalCount = 0; - data.results.map((doctor: DoctorModal) => { - if (doctor.count) { - totalCount += doctor.count; - } - }); - setTotalDoctors(totalCount); - } - }, - }, - ); - - let doctorList: any = null; - if (!doctorsList || !doctorsList.results.length) { - doctorList = ( -
    - {t("no_staff")} -
    - ); - } else { - doctorList = ( -
    -
    -
    -
    -
    - -
    -
    -
    - {t("total_staff")} -
    -

    {totalDoctors}

    -
    -
    -
    -
    - - {doctorsList.results.map((data: DoctorModal) => { - return ( - { - refetch(); - }} - {...data} - removeDoctor={() => refetch()} - /> - ); - })} -
    - ); - } - - return ( -
    -
    -
    -
    Staff Capacity
    - setDoctorCapacityModalOpen(true)} - disabled={doctorList.length === DOCTOR_SPECIALIZATION.length} - authorizeFor={NonReadOnlyUsers} - > - - Add Staff Types - -
    -
    - {doctorList} -
    -
    - - {doctorCapacityModalOpen && ( - setDoctorCapacityModalOpen(false)} - title="Add Staff Capacity" - className="max-w-md md:min-w-[600px]" - > - setDoctorCapacityModalOpen(false)} - handleUpdate={async () => { - refetch(); - }} - /> - - )} - updatePage(page)} - /> -
    - ); -}; diff --git a/src/components/Facility/StaffCapacity.tsx b/src/components/Facility/StaffCapacity.tsx deleted file mode 100644 index 53235dd68d0..00000000000 --- a/src/components/Facility/StaffCapacity.tsx +++ /dev/null @@ -1,241 +0,0 @@ -import { useReducer, useState } from "react"; -import { useTranslation } from "react-i18next"; - -import ButtonV2, { Cancel } from "@/components/Common/ButtonV2"; -import { DoctorModal } from "@/components/Facility/models"; -import { - FieldErrorText, - FieldLabel, -} from "@/components/Form/FormFields/FormField"; -import TextFormField from "@/components/Form/FormFields/TextFormField"; -import { FieldChangeEventHandler } from "@/components/Form/FormFields/Utils"; -import SelectMenuV2 from "@/components/Form/SelectMenuV2"; - -import { DOCTOR_SPECIALIZATION } from "@/common/constants"; - -import * as Notification from "@/Utils/Notifications"; -import routes from "@/Utils/request/api"; -import request from "@/Utils/request/request"; -import useTanStackQueryInstead from "@/Utils/request/useQuery"; - -interface DoctorCapacityProps extends DoctorModal { - facilityId: string; - handleClose: () => void; - handleUpdate: () => void; - className?: string; - id?: number; -} - -const initForm: any = { - area: "", - count: "", -}; - -const initialState = { - form: { ...initForm }, - errors: { ...initForm }, -}; - -const doctorCapacityReducer = (state = initialState, action: any) => { - switch (action.type) { - case "set_form": { - return { - ...state, - form: action.form, - }; - } - case "set_error": { - return { - ...state, - errors: action.errors, - }; - } - default: - return state; - } -}; - -const getAllowedDoctorTypes = (existing?: DoctorModal[]) => { - if (!existing) return [...DOCTOR_SPECIALIZATION]; - - return DOCTOR_SPECIALIZATION.map((specialization) => { - const disabled = existing.some((i) => i.area === specialization.id); - return { ...specialization, disabled }; - }); -}; - -export const StaffCapacity = (props: DoctorCapacityProps) => { - const { t } = useTranslation(); - const { facilityId, handleClose, handleUpdate, className, id } = props; - const [state, dispatch] = useReducer(doctorCapacityReducer, initialState); - const [isLoading, setIsLoading] = useState(false); - - const specializationsQuery = useTanStackQueryInstead(routes.listDoctor, { - pathParams: { facilityId }, - query: { - limit: DOCTOR_SPECIALIZATION.length - 1, - }, - }); - - const { loading } = useTanStackQueryInstead(routes.getDoctor, { - pathParams: { facilityId, id: `${id}` }, - prefetch: !!id, - onResponse: ({ data }) => { - if (!data) return; - dispatch({ - type: "set_form", - form: { area: data.area, count: data.count }, - }); - }, - }); - - const doctorTypes = getAllowedDoctorTypes(specializationsQuery.data?.results); - - const isLastOptionType = - doctorTypes.filter((i) => i.disabled).length === - DOCTOR_SPECIALIZATION.length - 1; - - const headerText = !id ? "Add Staff Capacity" : "Edit Staff Capacity"; - const buttonText = !id - ? `Save ${!isLastOptionType ? "& Add More" : "Staff Capacity"}` - : "Update Staff Capacity"; - - const validateData = () => { - const errors = { ...initForm }; - let invalidForm = false; - Object.keys(state.form).forEach((field) => { - if (!state.form[field]) { - errors[field] = t("field_required"); - invalidForm = true; - } - if (field === "count" && state.form[field] < 0) { - errors[field] = "Staff count cannot be negative"; - invalidForm = true; - } - }); - if (invalidForm) { - dispatch({ type: "set_error", errors }); - return false; - } - dispatch({ type: "set_error", errors }); - return true; - }; - - const handleFormFieldChange: FieldChangeEventHandler = (event) => { - const form = { ...state.form, [event.name]: event.value }; - dispatch({ type: "set_form", form }); - }; - - const handleSubmit = async (e: any) => { - const submitBtnID = e.currentTarget?.id; - e.preventDefault(); - const valid = validateData(); - if (valid) { - setIsLoading(true); - const data = { - area: Number(state.form.area), - count: Number(state.form.count), - }; - const { res } = await (id - ? request(routes.updateDoctor, { - pathParams: { facilityId, id: `${id}` }, - body: data, - }) - : request(routes.createDoctor, { - pathParams: { facilityId }, - body: data, - })); - setIsLoading(false); - if (res?.ok) { - specializationsQuery.refetch(); - dispatch({ type: "set_form", form: initForm }); - if (!id) { - Notification.Success({ msg: "Staff count added successfully" }); - } else { - Notification.Success({ msg: "Staff count updated successfully" }); - } - } - handleUpdate(); - - if (submitBtnID === "save-and-exit") handleClose(); - } - }; - - return ( -
    - {isLoading || loading || specializationsQuery.loading ? ( -
    -
    - - Loading... -
    -
    - ) : ( -
    -
    - - Staff Type - - type.id == state.form.area)?.id} - options={ - id ? doctorTypes : doctorTypes.filter((type) => !type.disabled) - } - optionLabel={(option) => option.text} - optionValue={(option) => option.id} - requiredError={state.errors.area.length !== 0} - onChange={(e) => - handleFormFieldChange({ - name: "area", - value: e || "", - }) - } - disabled={!!id} - /> - -
    -
    - -
    -
    - handleClose()} /> - {!isLastOptionType && headerText === "Add Staff Capacity" && ( - - Save Staff Capacity - - )} - - {buttonText} - -
    -
    - )} -
    - ); -}; diff --git a/src/components/Facility/StaffCountCard.tsx b/src/components/Facility/StaffCountCard.tsx deleted file mode 100644 index 0c0984172b1..00000000000 --- a/src/components/Facility/StaffCountCard.tsx +++ /dev/null @@ -1,118 +0,0 @@ -import { useState } from "react"; - -import ButtonV2 from "@/components/Common/ButtonV2"; -import ConfirmDialog from "@/components/Common/ConfirmDialog"; -import DialogModal from "@/components/Common/Dialog"; -import { StaffCapacity } from "@/components/Facility/StaffCapacity"; -import { DoctorModal } from "@/components/Facility/models"; -import { DoctorIcon } from "@/components/TeleIcu/Icons/DoctorIcon"; - -import { DOCTOR_SPECIALIZATION } from "@/common/constants"; - -import { NonReadOnlyUsers } from "@/Utils/AuthorizeFor"; -import * as Notification from "@/Utils/Notifications"; -import routes from "@/Utils/request/api"; -import request from "@/Utils/request/request"; - -interface DoctorsCountProps extends DoctorModal { - facilityId: string; - removeDoctor: (doctorId: number | undefined) => void; - handleUpdate: () => void; -} - -const StaffCountCard = (props: DoctorsCountProps) => { - const specialization = DOCTOR_SPECIALIZATION.find((i) => i.id === props.area); - const [openDeleteDialog, setOpenDeleteDialog] = useState(false); - const [open, setOpen] = useState(false); - const [selectedId, setSelectedId] = useState(-1); - - const handleDeleteSubmit = async () => { - if (!props.area) return; - - const { res } = await request(routes.deleteDoctor, { - pathParams: { facilityId: props.facilityId, area: `${props.area}` }, - }); - - if (res?.ok) { - props.removeDoctor(props.id); - Notification.Success({ - msg: "Staff specialization type deleted successfully", - }); - } - }; - - const handleDeleteClose = () => { - setOpenDeleteDialog(false); - }; - - return ( -
    -
    -
    -
    - -
    -
    -
    - {specialization?.text} -
    -

    {props.count}

    -
    -
    -
    - { - setSelectedId(props.area || 0); - setOpen(true); - }} - authorizeFor={NonReadOnlyUsers} - > - Edit - - setOpenDeleteDialog(true)} - authorizeFor={NonReadOnlyUsers} - > - Delete - -
    - -
    - {open && ( - setOpen(false)} - title="Update Staff Capacity" - > - { - setOpen(false); - }} - handleUpdate={() => { - props.handleUpdate(); - setOpen(false); - }} - id={selectedId} - /> - - )} -
    - ); -}; - -export default StaffCountCard; diff --git a/src/components/Facility/TriageForm.tsx b/src/components/Facility/TriageForm.tsx deleted file mode 100644 index 607adb0172f..00000000000 --- a/src/components/Facility/TriageForm.tsx +++ /dev/null @@ -1,321 +0,0 @@ -import dayjs from "dayjs"; -import { useReducer, useState } from "react"; -import { useTranslation } from "react-i18next"; - -import Card from "@/CAREUI/display/Card"; -import CareIcon from "@/CAREUI/icons/CareIcon"; - -import { Cancel, Submit } from "@/components/Common/ButtonV2"; -import ConfirmDialog from "@/components/Common/ConfirmDialog"; -import Loading from "@/components/Common/Loading"; -import Page from "@/components/Common/Page"; -import { PatientStatsModel } from "@/components/Facility/models"; -import DateFormField from "@/components/Form/FormFields/DateFormField"; -import TextFormField from "@/components/Form/FormFields/TextFormField"; -import { FieldChangeEvent } from "@/components/Form/FormFields/Utils"; - -import useAppHistory from "@/hooks/useAppHistory"; - -import * as Notification from "@/Utils/Notifications"; -import routes from "@/Utils/request/api"; -import request from "@/Utils/request/request"; -import useTanStackQueryInstead from "@/Utils/request/useQuery"; -import { dateQueryString, scrollTo } from "@/Utils/utils"; - -interface Props extends PatientStatsModel { - facilityId: string; - id?: string; -} - -const initForm: any = { - entry_date: null, - num_patients_visited: "", - num_patients_home_quarantine: "", - num_patients_isolation: "", - num_patient_referred: "", - num_patient_confirmed_positive: "", -}; - -const initialState = { - form: { ...initForm }, - errors: { ...initForm }, -}; - -const triageFormReducer = (state = initialState, action: any) => { - switch (action.type) { - case "set_form": { - return { - ...state, - form: action.form, - }; - } - case "set_error": { - return { - ...state, - errors: action.errors, - }; - } - default: - return state; - } -}; - -export const TriageForm = ({ facilityId, id }: Props) => { - const { t } = useTranslation(); - const { goBack } = useAppHistory(); - const [state, dispatch] = useReducer(triageFormReducer, initialState); - const [isLoading, setIsLoading] = useState(false); - const [openModalForExistingTriage, setOpenModalForExistingTriage] = - useState(false); - const headerText = !id ? "Add Triage" : "Edit Triage"; - const buttonText = !id ? "Save Triage" : "Update Triage"; - - const triageDetailsQuery = useTanStackQueryInstead(routes.getTriageDetails, { - pathParams: { facilityId, id: id! }, - prefetch: !!id, - onResponse: ({ data }) => { - if (!data) return; - dispatch({ - type: "set_form", - form: { - ...data, - entry_date: data.entry_date ? dayjs(data.entry_date).toDate() : null, - }, - }); - }, - }); - - const patientStatsQuery = useTanStackQueryInstead(routes.getTriage, { - pathParams: { facilityId }, - }); - - const patientStatsData = patientStatsQuery.data?.results ?? []; - - const facilityQuery = useTanStackQueryInstead(routes.getAnyFacility, { - pathParams: { id: facilityId }, - }); - const facilityName = facilityQuery.data?.name ?? ""; - - const validateForm = () => { - const errors = { ...initForm }; - let invalidForm = false; - Object.keys(state.form).forEach((field, _) => { - switch (field) { - case "entry_date": - if (!state.form[field]) { - errors[field] = t("field_required"); - invalidForm = true; - } - return; - case "num_patients_visited": - case "num_patients_home_quarantine": - case "num_patients_isolation": - case "num_patient_referred": - case "num_patient_confirmed_positive": - if (state.form[field] != null && state.form[field] < 0) { - errors[field] = "Value must be greater than or equal to 0"; - invalidForm = true; - } - return; - - default: - return; - } - }); - if (invalidForm) { - dispatch({ type: "set_error", errors }); - const firstError = Object.keys(errors).find((e) => errors[e]); - if (firstError) { - scrollTo(firstError); - } - return false; - } - dispatch({ type: "set_error", errors }); - return true; - }; - const isTriageExist = (data: any) => { - if ( - patientStatsData.filter( - (triageData) => triageData.entry_date === data.entry_date, - ).length === 1 - ) { - return true; - } - return false; - }; - - const handleSubmit = async () => { - setOpenModalForExistingTriage(false); - const validForm = validateForm(); - if (validForm) { - const data = { - entry_date: dateQueryString(state.form.entry_date), - num_patients_visited: Number(state.form.num_patients_visited), - num_patients_home_quarantine: Number( - state.form.num_patients_home_quarantine, - ), - num_patients_isolation: Number(state.form.num_patients_isolation), - num_patient_referred: Number(state.form.num_patient_referred), - num_patient_confirmed_positive: Number( - state.form.num_patient_confirmed_positive, - ), - }; - //proceed if the triage does not exist or proceed has allowed to proceed after seeing the modal or it's a edit feature of the same date - if ( - !isTriageExist(data) || - openModalForExistingTriage || - buttonText === "Update Triage" - ) { - setOpenModalForExistingTriage(false); - setIsLoading(true); - const { res } = await request(routes.createTriage, { - pathParams: { facilityId }, - body: data, - }); - setIsLoading(false); - if (res?.ok) { - dispatch({ type: "set_form", form: initForm }); - if (id) { - Notification.Success({ msg: "Triage updated successfully" }); - } else { - Notification.Success({ msg: "Triage created successfully" }); - } - goBack(); - } - } else { - setOpenModalForExistingTriage(true); - } - } - }; - - const handleFormFieldChange = (event: FieldChangeEvent) => { - dispatch({ - type: "set_form", - form: { ...state.form, [event.name]: event.value }, - }); - }; - - if ( - isLoading || - facilityQuery.loading || - triageDetailsQuery.loading || - patientStatsQuery.loading - ) { - return ; - } - - return ( -
    - - - -

    A Triage already exist on this date

    -
    - } - description="A Triage already exist on this date, If you wish to proceed then the existing triage will be over - written!" - variant="danger" - show={openModalForExistingTriage} - onClose={() => setOpenModalForExistingTriage(false)} - className="w-[48rem]" - action="Proceed" - onConfirm={handleSubmit} - /> - -
    - -
    { - e.preventDefault(); - handleSubmit(); - }} - > -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    -
    - goBack()} /> - -
    - -
    -
    - - - ); -}; diff --git a/src/components/Facility/models.tsx b/src/components/Facility/models.tsx index a984efe6283..d25258be12d 100644 --- a/src/components/Facility/models.tsx +++ b/src/components/Facility/models.tsx @@ -67,16 +67,8 @@ export interface FacilityModel { latitude: number; longitude: number; }; - oxygen_capacity?: number; phone_number?: string; - type_b_cylinders?: number; - type_c_cylinders?: number; - type_d_cylinders?: number; middleware_address?: string; - expected_type_b_cylinders?: number; - expected_type_c_cylinders?: number; - expected_type_d_cylinders?: number; - expected_oxygen_requirement?: number; local_body_object?: LocalBodyModel; district_object?: DistrictModel; state_object?: StateModel; @@ -115,20 +107,6 @@ export interface FacilitySpokeRequest { export interface FacilitySpokeErrors {} -export interface CapacityModal { - id?: number; - room_type?: number; - modified_date?: any; - total_capacity?: number; - current_capacity?: number; -} - -export interface DoctorModal { - id?: number; - area?: number; - count?: number; -} - export interface OptionsType { id: number; text: string; @@ -225,17 +203,6 @@ export interface ConsultationModel { has_consents?: (typeof CONSENT_TYPE_CHOICES)[number]["id"][]; } -export interface PatientStatsModel { - id?: string; - entryDate?: string; - num_patients_visited?: number; - num_patients_home_quarantine?: number; - num_patients_isolation?: number; - num_patient_referred?: number; - entry_date?: string; - num_patient_confirmed_positive?: number; -} - export interface DupPatientModel { id: number; gender: string; diff --git a/src/components/Patient/PatientRegister.tsx b/src/components/Patient/PatientRegister.tsx index eb0594baa82..daca5e90a21 100644 --- a/src/components/Patient/PatientRegister.tsx +++ b/src/components/Patient/PatientRegister.tsx @@ -14,13 +14,13 @@ import Loading from "@/components/Common/Loading"; import PageTitle from "@/components/Common/PageTitle"; import Spinner from "@/components/Common/Spinner"; import Error404 from "@/components/ErrorPages/404"; -import { ILocalBodies } from "@/components/ExternalResult/models"; import DuplicatePatientDialog from "@/components/Facility/DuplicatePatientDialog"; import TransferPatientDialog from "@/components/Facility/TransferPatientDialog"; import { DistrictModel, DupPatientModel, FacilityModel, + LocalBodyModel, WardModel, } from "@/components/Facility/models"; import { @@ -205,7 +205,7 @@ export const PatientRegister = (props: PatientRegisterProps) => { const [isLocalbodyLoading, setIsLocalbodyLoading] = useState(false); const [isWardLoading, setIsWardLoading] = useState(false); const [districts, setDistricts] = useState([]); - const [localBody, setLocalBody] = useState([]); + const [localBody, setLocalBody] = useState([]); const [ward, setWard] = useState([]); const [ageInputType, setAgeInputType] = useState< "date_of_birth" | "age" | "alert_for_age"