diff --git a/cypress/e2e/assets_spec/AssetHomepage.cy.ts b/cypress/e2e/assets_spec/AssetHomepage.cy.ts index e19f885db72..fc195c7a803 100644 --- a/cypress/e2e/assets_spec/AssetHomepage.cy.ts +++ b/cypress/e2e/assets_spec/AssetHomepage.cy.ts @@ -113,7 +113,6 @@ rolesToTest.forEach((role) => { it("Export the list of assets in CSV & Json", () => { if (role === "districtAdmin") { assetHome.selectAssetImportButton("click"); - cy.wait(2000); assetHome.selectJsonExportButton(); assetHome.selectAssetImportButton("click"); assetHome.selectCsvExportButton(); diff --git a/cypress/e2e/facility_spec/FacilityCreation.cy.ts b/cypress/e2e/facility_spec/FacilityCreation.cy.ts index d2893166745..4a07a665896 100644 --- a/cypress/e2e/facility_spec/FacilityCreation.cy.ts +++ b/cypress/e2e/facility_spec/FacilityCreation.cy.ts @@ -65,7 +65,6 @@ describe("Facility Creation with multiple user roles", () => { beforeEach(() => { cy.viewport(1280, 720); cy.restoreLocalStorage(); - cy.awaitUrl("/facility"); }); it("Create a new facility with all fields | Edit Existing Data | Verify its reflection", () => { diff --git a/cypress/e2e/facility_spec/FacilityHomepage.cy.ts b/cypress/e2e/facility_spec/FacilityHomepage.cy.ts index 0aa8518a6d1..c43106ba869 100644 --- a/cypress/e2e/facility_spec/FacilityHomepage.cy.ts +++ b/cypress/e2e/facility_spec/FacilityHomepage.cy.ts @@ -196,7 +196,9 @@ describe("Facility Homepage Function", () => { }); it("Verify the bed capacity badge reflection", () => { + facilityHome.interceptFacilitySearchReq(); facilityHome.typeFacilitySearch(facilityWithNoAvailableBeds); + facilityHome.verifyFacilitySearchReq(); facilityHome.assertFacilityInCard(facilityWithNoAvailableBeds); cy.url().then((url) => { const facilityUrl = url.toString(); diff --git a/cypress/e2e/facility_spec/FacilityInventory.cy.ts b/cypress/e2e/facility_spec/FacilityInventory.cy.ts index b3f77479763..b79998fd5cd 100644 --- a/cypress/e2e/facility_spec/FacilityInventory.cy.ts +++ b/cypress/e2e/facility_spec/FacilityInventory.cy.ts @@ -25,15 +25,20 @@ describe("Inventory Management Section", () => { it("Add New Inventory | Modify data and delete last entry ", () => { // add a new item + facilityPage.interceptManageInventoryItem(); facilityPage.clickManageInventory(); + facilityPage.verifyManageInventoryItem(); facilityPage.fillInventoryDetails("PPE", "Add Stock", "10"); facilityPage.clickAddInventory(); facilityPage.verifySuccessNotification("Inventory created successfully"); + cy.closeNotification(); facilityPage.clickManageInventory(); // modify the new item facilityPage.fillInventoryDetails("PPE", "Use Stock", "5"); facilityPage.clickAddInventory(); - facilityPage.verifySuccessNotification("Inventory created successfully"); + facilityPage.verifySuccessNotification( + "Inventory use stock updated successfully", + ); // verify the new modification facilityPage.verifyPpeQuantity("PPE"); facilityPage.verifyPpeQuantity("5"); @@ -43,7 +48,6 @@ describe("Inventory Management Section", () => { // verify the last entry deletion facilityPage.verifyStockInRow("#row-0", "Added Stock"); facilityPage.verifyStockInRow("#row-1", "Used Stock"); - cy.wait(3000); facilityHome.navigateBack(); facilityPage.verifyPpeQuantity("PPE"); }); @@ -57,9 +61,10 @@ describe("Inventory Management Section", () => { cy.closeNotification(); // Verify Backend minimum badge facilityPage.verifyBadgeWithText(".badge-danger", "Low Stock"); + facilityPage.interceptMinimumQuantity(); // modify with manual minimum badge - facilityPage.clickAddMinimumQuanitity(); - cy.wait(3000); + facilityPage.clickAddMinimumQuantity(); + facilityPage.verifyMinimumQuantity(); cy.get("body").then(($body) => { if ($body.find("#update-minimum-quantity").is(":visible")) { // If the 'update-minimum-quantity' element is visible, click it diff --git a/cypress/e2e/patient_spec/PatientConsultationCreation.cy.ts b/cypress/e2e/patient_spec/PatientConsultationCreation.cy.ts index a257d127942..2969d2ddb93 100644 --- a/cypress/e2e/patient_spec/PatientConsultationCreation.cy.ts +++ b/cypress/e2e/patient_spec/PatientConsultationCreation.cy.ts @@ -104,8 +104,9 @@ describe("Patient Consultation in multiple combination", () => { patientPrescription.selectMedicine(medicineOne); patientPrescription.enterDosage("3"); patientPrescription.selectDosageFrequency("Twice daily"); + patientPrescription.interceptPrescriptions(); cy.clickSubmitButton("Submit"); - cy.wait(2000); + patientPrescription.verifyPrescription(); cy.verifyNotification("Medicine prescribed"); patientPrescription.clickReturnToDashboard(); // Verify the data's across the dashboard @@ -376,7 +377,9 @@ describe("Patient Consultation in multiple combination", () => { it("Edit created consultation to existing patient", () => { patientPage.visitPatient("Dummy Patient Thirteen"); + patientConsultationPage.interceptConsultation(); patientConsultationPage.clickEditConsultationButton(); + patientConsultationPage.verifyConsultation(); patientConsultationPage.typePatientIllnessHistory("editted"); patientConsultationPage.selectPatientDiagnosis( diagnosis5, diff --git a/cypress/e2e/patient_spec/PatientConsultationDischarge.cy.ts b/cypress/e2e/patient_spec/PatientConsultationDischarge.cy.ts index b7ef6936804..50af6052581 100644 --- a/cypress/e2e/patient_spec/PatientConsultationDischarge.cy.ts +++ b/cypress/e2e/patient_spec/PatientConsultationDischarge.cy.ts @@ -35,7 +35,9 @@ describe("Patient Discharge based on multiple reason", () => { patientDischarge.clickDischarge(); patientDischarge.selectDischargeReason(patientDischargeReason4); cy.clickSubmitButton("Confirm Discharge"); + patientDischarge.interceptDischargePatient(); cy.clickSubmitButton("Acknowledge & Submit"); + patientDischarge.verifyDischargePatient(); cy.verifyNotification("Patient Discharged Successfully"); cy.closeNotification(); // Verify the consultation dashboard reflection @@ -53,7 +55,9 @@ describe("Patient Discharge based on multiple reason", () => { patientDischarge.typeDischargeNote(patientDeathCause); patientDischarge.typeDoctorName(doctorName); cy.clickSubmitButton("Confirm Discharge"); + patientDischarge.interceptDischargePatient(); cy.clickSubmitButton("Acknowledge & Submit"); + patientDischarge.verifyDischargePatient(); cy.verifyNotification("Patient Discharged Successfully"); cy.closeNotification(); // Verify the consultation dashboard reflection @@ -76,10 +80,10 @@ describe("Patient Discharge based on multiple reason", () => { patientDischarge.clickClearButton(); // select a non-registered facility and perform the discharge patientDischarge.typeReferringFacility(referringFreetextFacility); - cy.wait(2000); cy.clickSubmitButton("Confirm Discharge"); + patientDischarge.interceptDischargePatient(); cy.clickSubmitButton("Acknowledge & Submit"); - cy.wait(2000); + patientDischarge.verifyDischargePatient(); cy.verifyNotification("Patient Discharged Successfully"); cy.closeNotification(); // Verify the consultation dashboard reflection @@ -106,12 +110,12 @@ describe("Patient Discharge based on multiple reason", () => { patientPrescription.selectDosageFrequency("Twice daily"); cy.clickSubmitButton("Submit"); cy.verifyNotification("Medicine prescribed"); - cy.wait(2000); cy.closeNotification(); // submit the discharge pop-up cy.clickSubmitButton("Confirm Discharge"); + patientDischarge.interceptDischargePatient(); cy.clickSubmitButton("Acknowledge & Submit"); - cy.wait(2000); + patientDischarge.verifyDischargePatient(); cy.verifyNotification("Patient Discharged Successfully"); cy.closeNotification(); // Verify the consultation dashboard reflection diff --git a/cypress/e2e/patient_spec/PatientHomepage.cy.ts b/cypress/e2e/patient_spec/PatientHomepage.cy.ts index 8949fc3e324..8f5ac03a9ef 100644 --- a/cypress/e2e/patient_spec/PatientHomepage.cy.ts +++ b/cypress/e2e/patient_spec/PatientHomepage.cy.ts @@ -161,7 +161,6 @@ describe("Patient Homepage present functionalities", () => { .then((patientOne: string) => { firstPatientPageOne = patientOne.trim(); pageNavigation.navigateToNextPage(); - cy.wait(2000); pageNavigation.verifyCurrentPageNumber(2); cy.get('[data-cy="patient"]') .first() diff --git a/cypress/e2e/patient_spec/PatientLogUpdate.cy.ts b/cypress/e2e/patient_spec/PatientLogUpdate.cy.ts index ec5aef250dc..963f62a76e0 100644 --- a/cypress/e2e/patient_spec/PatientLogUpdate.cy.ts +++ b/cypress/e2e/patient_spec/PatientLogUpdate.cy.ts @@ -13,6 +13,7 @@ describe("Patient Log Update in Normal, Critical and TeleIcu", () => { const patientInvestigation = new PatientInvestigation(); const patientPrescription = new PatientPrescription(); const patientCategory = "Moderate"; + const patientModifiedCategory = "Critical"; const additionalSymptoms = "Fever"; const physicalExamination = "physical examination details"; const otherExamination = "Other"; @@ -58,7 +59,9 @@ describe("Patient Log Update in Normal, Critical and TeleIcu", () => { cy.clickSubmitButton("Update Consultation"); cy.verifyNotification("Consultation updated successfully"); cy.closeNotification(); + patientPage.interceptGetPatient(); patientLogupdate.clickLogupdate(); + patientPage.verifyGetPatientResponse(); patientLogupdate.typePhysicalExamination(physicalExamination); patientLogupdate.selectRoundType("Tele-medicine Log"); patientLogupdate.selectPatientCategory(patientCategory); @@ -80,11 +83,15 @@ describe("Patient Log Update in Normal, Critical and TeleIcu", () => { it("Create a new Progress log update for a admitted patient and edit it", () => { patientPage.visitPatient(patientOne); + patientLogupdate.interceptConsultationBed(); patientLogupdate.clickLogupdate(); + patientLogupdate.verifyConsultationBed(); cy.verifyNotification("Please assign a bed to the patient"); patientLogupdate.selectBed(bedOne); cy.closeNotification(); + patientPage.interceptGetPatient(); patientLogupdate.clickLogupdate(); + patientPage.verifyGetPatientResponse(); // Only will be using random non-unique progress note fields patientLogupdate.selectRoundType("Progress Note"); patientLogupdate.selectPatientCategory(patientCategory); @@ -112,15 +119,18 @@ describe("Patient Log Update in Normal, Critical and TeleIcu", () => { cy.verifyNotification("Medicine prescribed"); cy.closeNotification(); // Submit the doctors log update + patientLogupdate.interceptDailyRounds(); cy.clickSubmitButton("Save and Continue"); - cy.wait(2000); + patientLogupdate.verifyDailyRounds(); cy.verifyNotification("Progress Note created successfully"); cy.closeNotification(); // modify the relevant critical care log update patientLogupdate.selectCriticalCareSection("Neurological Monitoring"); cy.get("#consciousness_level-option-RESPONDS_TO_PAIN").click(); cy.get("#left_pupil_light_reaction-option-FIXED").click(); + patientLogupdate.interceptpatchDailyRounds(); cy.clickSubmitButton("Update Details"); + patientLogupdate.verifypatchDailyRounds(); cy.verifyNotification( "Neurological Monitoring details succesfully updated.", ); @@ -141,6 +151,9 @@ describe("Patient Log Update in Normal, Critical and TeleIcu", () => { ]); // verify the edit functionality patientLogupdate.clickUpdateDetail(); + patientLogupdate.verifyPatientCategory(patientCategory); + patientLogupdate.verifyRoundType("Progress Note"); + patientLogupdate.selectPatientCategory(patientModifiedCategory); patientLogupdate.typeSystolic(patientModifiedSystolic); patientLogupdate.typeDiastolic(patientModifiedDiastolic); cy.clickSubmitButton("Continue"); @@ -156,7 +169,9 @@ describe("Patient Log Update in Normal, Critical and TeleIcu", () => { patientLogupdate.clickLogupdate(); patientLogupdate.selectRoundType("Detailed Update"); patientLogupdate.selectPatientCategory(patientCategory); + patientLogupdate.interceptDailyRounds(); cy.clickSubmitButton("Save and Continue"); + patientLogupdate.verifyDailyRounds(); cy.verifyNotification("Detailed Update created successfully"); cy.closeNotification(); // Select two Section - First One is Respiratory Support @@ -235,9 +250,12 @@ describe("Patient Log Update in Normal, Critical and TeleIcu", () => { cy.verifyNotification("Please assign a bed to the patient"); patientLogupdate.selectBed(bedThree); cy.closeNotification(); + patientPage.interceptGetPatient(); patientLogupdate.clickLogupdate(); - patientLogupdate.typePhysicalExamination(physicalExamination); + patientPage.verifyGetPatientResponse(); + patientLogupdate.verifyRoundType("Brief Update"); patientLogupdate.selectPatientCategory(patientCategory); + patientLogupdate.typePhysicalExamination(physicalExamination); patientLogupdate.typeOtherDetails(otherExamination); patientLogupdate.selectSymptomsDate("01012024"); patientLogupdate.typeAndMultiSelectSymptoms("fe", ["Fever"]); @@ -251,9 +269,11 @@ describe("Patient Log Update in Normal, Critical and TeleIcu", () => { patientLogupdate.selectRhythm(patientRhythmType); patientLogupdate.typeRhythm(patientRhythm); cy.get("#consciousness_level-option-RESPONDS_TO_PAIN").click(); + patientConsultationPage.interceptConsultation(); cy.clickSubmitButton("Save"); - cy.wait(2000); + patientConsultationPage.verifyConsultation(); cy.verifyNotification("Brief Update created successfully"); + cy.closeNotification(); // Verify the card content cy.get("#basic-information").scrollIntoView(); cy.verifyContentPresence("#encounter-symptoms", [additionalSymptoms]); @@ -267,11 +287,13 @@ describe("Patient Log Update in Normal, Critical and TeleIcu", () => { cy.verifyNotification("Consultation updated successfully"); cy.closeNotification(); patientLogupdate.clickLogupdate(); + patientLogupdate.verifyRoundType("Brief Update"); // Verify the default round type + patientLogupdate.selectRoundType("Brief Update"); + patientLogupdate.selectPatientCategory(patientCategory); patientLogupdate.typePhysicalExamination(physicalExamination); patientLogupdate.typeOtherDetails(otherExamination); patientLogupdate.selectSymptomsDate("01012024"); patientLogupdate.typeAndMultiSelectSymptoms("fe", ["Fever"]); - patientLogupdate.selectPatientCategory(patientCategory); patientLogupdate.typeSystolic(patientSystolic); patientLogupdate.typeDiastolic(patientDiastolic); patientLogupdate.typePulse(patientPulse); @@ -303,10 +325,10 @@ describe("Patient Log Update in Normal, Critical and TeleIcu", () => { patientRhythm, ]); patientLogupdate.clickUpdateDetail(); - patientLogupdate.clearIntoElementById("#systolic"); - patientLogupdate.typeSystolic(patientModifiedSystolic); - patientLogupdate.clearIntoElementById("#diastolic"); - patientLogupdate.typeDiastolic(patientModifiedDiastolic); + patientLogupdate.verifyPatientCategory(patientCategory); + patientLogupdate.verifyRoundType("Brief Update"); + patientLogupdate.typeSystolic(patientModifiedSystolic, true); + patientLogupdate.typeDiastolic(patientModifiedDiastolic, true); cy.clickSubmitButton("Continue"); cy.verifyNotification("Brief Update updated successfully"); cy.contains("button", "Log Updates").click(); diff --git a/cypress/e2e/patient_spec/PatientPrescription.cy.ts b/cypress/e2e/patient_spec/PatientPrescription.cy.ts index 61f8067eea0..bc883e7a5fd 100644 --- a/cypress/e2e/patient_spec/PatientPrescription.cy.ts +++ b/cypress/e2e/patient_spec/PatientPrescription.cy.ts @@ -113,7 +113,6 @@ describe("Patient Medicine Administration", () => { cy.closeNotification(); // Administer the medicine in edit form patientPrescription.clickAdministerButton(); - cy.wait(2000); patientPrescription.enterAdministerDosage(medicineBaseDosage); patientPrescription.enterAdministerNotes(medicineAdministerNote); cy.clickSubmitButton("Administer Medicine"); diff --git a/cypress/e2e/patient_spec/PatientRegistration.cy.ts b/cypress/e2e/patient_spec/PatientRegistration.cy.ts index b11d0f8f585..a8b1e47bb4d 100644 --- a/cypress/e2e/patient_spec/PatientRegistration.cy.ts +++ b/cypress/e2e/patient_spec/PatientRegistration.cy.ts @@ -1,3 +1,5 @@ +import { PatientConsultationPage } from "pageobject/Patient/PatientConsultation"; + import LoginPage from "../../pageobject/Login/LoginPage"; import { PatientData, @@ -6,7 +8,11 @@ import { import PatientInsurance from "../../pageobject/Patient/PatientInsurance"; import PatientMedicalHistory from "../../pageobject/Patient/PatientMedicalHistory"; import PatientTransfer from "../../pageobject/Patient/PatientTransfer"; -import { generatePhoneNumber } from "../../pageobject/utils/constants"; +import { + generatePatientName, + generatePhoneNumber, + generateRandomAddress, +} from "../../pageobject/utils/constants"; const yearOfBirth = "2001"; @@ -15,38 +21,21 @@ const calculateAge = () => { return currentYear - parseInt(yearOfBirth); }; -const getRelativeDateString = (deltaDays = 0) => { - const date = new Date(); - if (deltaDays) { - date.setDate(date.getDate() + deltaDays); - } - return date - .toLocaleDateString("en-IN", { - day: "2-digit", - month: "2-digit", - year: "numeric", - }) - .replace(/\//g, ""); -}; - describe("Patient Creation with consultation", () => { const loginPage = new LoginPage(); const patientPage = new PatientPage(); const patientTransfer = new PatientTransfer(); const patientInsurance = new PatientInsurance(); const patientMedicalHistory = new PatientMedicalHistory(); + const patientConsultationPage = new PatientConsultationPage(); const phone_number = generatePhoneNumber(); const age = calculateAge(); const patientFacility = "Dummy Facility 40"; const patientDateOfBirth = "01012001"; - const patientMenstruationStartDate = getRelativeDateString(-10); - const patientDateOfDelivery = getRelativeDateString(-20); - const patientOneName = "Great Napolean 14"; + const patientOneName = generatePatientName(); const patientOneGender = "Male"; const patientOneUpdatedGender = "Female"; - const patientOneAddress = `149/J, 3rd Block, - Aluva - Ernakulam, Kerala - 682001`; + const patientOneAddress = generateRandomAddress(true); const patientOnePincode = "682001"; const patientOneState = "Kerala"; const patientOneDistrict = "Ernakulam"; @@ -115,14 +104,11 @@ describe("Patient Creation with consultation", () => { it("Create a new patient with all field in registration form and no consultation", () => { patientPage.createPatientWithData(newPatientData); - // Verify the patient details patientPage.clickCancelButton(); - cy.wait(3000); - patientPage.savePatientUrl(); + // Verify the patient details patientPage.verifyPatientDashboardDetails( patientOneGender, age, - patientOneName, phone_number, phone_number, yearOfBirth, @@ -150,21 +136,15 @@ describe("Patient Creation with consultation", () => { patientPage.verifyPatientNameList(patientOneName); }); - it("Edit the patient details with no consultation and verify", () => { - patientPage.interceptFacilities(); - patientPage.visitUpdatePatientUrl(); - patientPage.verifyStatusCode(); - patientPage.patientformvisibility(); - // change the gender to female and input data to related changed field - cy.wait(3000); + it("Edit the patient details and verify its reflection", () => { + const patientName = "Dummy Patient Two"; + patientPage.visitPatient(patientName); + patientConsultationPage.clickPatientDetails(); + patientPage.clickPatientUpdateDetails(); patientPage.selectPatientGender(patientOneUpdatedGender); patientPage.typePatientDateOfBirth(patientDateOfBirth); - patientPage.clickPatientAntenatalStatusYes(); - patientPage.typeLastMenstruationStartDate(patientMenstruationStartDate); - patientPage.clickPatientPostPartumStatusYes(); - patientPage.typeDateOfDelivery(patientDateOfDelivery); patientPage.selectPatientBloodGroup(patientOneUpdatedBloodGroup); - // Edit the patient consultation , select none medical history and multiple health ID + // select none medical history and add multiple health ID patientMedicalHistory.clickNoneMedicialHistory(); patientInsurance.clickAddInsruanceDetails(); patientInsurance.typePatientInsuranceDetail( @@ -197,28 +177,13 @@ describe("Patient Creation with consultation", () => { patientOneSecondInsurerName, ); patientPage.clickUpdatePatient(); - cy.wait(3000); patientPage.verifyPatientUpdated(); - patientPage.visitPatientUrl(); - // Verify Female Gender change reflection, No Medical History and Insurance Details - cy.wait(5000); - patientPage.verifyPatientDashboardDetails( - patientOneUpdatedGender, - age, - patientOneName, - phone_number, - phone_number, - yearOfBirth, - patientOneUpdatedBloodGroup, - patientOccupation, - ); // Verify No medical history patientMedicalHistory.verifyNoSymptosPresent("Diabetes"); // verify insurance details and dedicatd page cy.get("[data-testid=patient-details]") .contains("Member ID") .scrollIntoView(); - cy.wait(2000); patientInsurance.verifyPatientPolicyDetails( patientOneFirstSubscriberId, patientOneFirstPolicyId, @@ -249,7 +214,7 @@ describe("Patient Creation with consultation", () => { // allow the transfer button of a patient patientTransfer.clickAllowPatientTransferButton(); // Verify the patient error message for the same facility - cy.awaitUrl("/patients"); + cy.visit("/patients"); patientPage.createPatient(); patientPage.selectFacility(patientTransferFacility); patientPage.patientformvisibility(); diff --git a/cypress/e2e/users_spec/UsersCreation.cy.ts b/cypress/e2e/users_spec/UsersCreation.cy.ts index d93707617ff..38ad0c907c4 100644 --- a/cypress/e2e/users_spec/UsersCreation.cy.ts +++ b/cypress/e2e/users_spec/UsersCreation.cy.ts @@ -108,9 +108,9 @@ describe("User Creation", () => { userProfilePage.clearWorkingHours(); userProfilePage.typeWorkingHours(weeklyWorkingHrs); userProfilePage.typeDateOfBirth(dob); - cy.intercept("PATCH", "/api/v1/users/*").as("updateUser"); + userProfilePage.interceptUpdateUsers(); userProfilePage.clickUpdateButton(); - cy.wait("@updateUser").its("response.statusCode").should("eq", 200); + userProfilePage.verifyUpdateUsersResponse(); cy.verifyContentPresence("#contactno-profile-details", [ "+91" + phoneNumber, ]); @@ -158,9 +158,9 @@ describe("User Creation", () => { userCreationPage.selectGender(gender); userCreationPage.selectState(state); userCreationPage.selectDistrict(district); - cy.intercept("POST", "/api/v1/users/add_user/").as("createUser"); + userCreationPage.interceptCreateUser(); userCreationPage.clickSaveUserButton(); - cy.wait("@createUser").its("response.statusCode").should("eq", 201); + userCreationPage.verifyCreateUser(); cy.verifyNotification("User added successfully"); userPage.typeInSearchInput(username); userPage.checkUsernameText(username); diff --git a/cypress/e2e/users_spec/UsersManage.cy.ts b/cypress/e2e/users_spec/UsersManage.cy.ts index 8d7ac8695c6..b1968ed2b4c 100644 --- a/cypress/e2e/users_spec/UsersManage.cy.ts +++ b/cypress/e2e/users_spec/UsersManage.cy.ts @@ -230,14 +230,15 @@ describe("Manage User", () => { userPage.checkUsernameText(usernameforworkinghour); manageUserPage.clickMoreDetailsButton(usernameforworkinghour); manageUserPage.verifyMoreDetailsPage(); + manageUserPage.interceptLinkedSkillTab(); manageUserPage.clickLinkedSkillTab(); - cy.wait(500); + manageUserPage.verifyLinkedSkillResponse(); manageUserPage.verifyLinkedSkillsTabPage(); manageUserPage.selectSkillFromDropdown(linkedskill); + manageUserPage.interceptAddSkill(); manageUserPage.clickAddSkillButton(usernameforworkinghour); - cy.wait(500); + manageUserPage.verifyAddSkillResponse(); manageUserPage.assertSkillInAddedUserSkills(linkedskill); - cy.wait(500); manageUserPage.navigateToProfile(); cy.verifyContentPresence("#username-profile-details", [ usernameforworkinghour, diff --git a/cypress/pageobject/Asset/AssetHome.ts b/cypress/pageobject/Asset/AssetHome.ts index e127b785100..1c3cdd20399 100644 --- a/cypress/pageobject/Asset/AssetHome.ts +++ b/cypress/pageobject/Asset/AssetHome.ts @@ -69,7 +69,7 @@ export class AssetHome { selectAssetImportButton(action: "click" | "verifyNotExist"): void { const selector = "[data-testid=import-asset-button]"; if (action === "click") { - cy.get(selector).click(); + cy.get(selector).scrollIntoView().should("be.visible").click(); } else if (action === "verifyNotExist") { cy.get(selector).should("not.exist"); } @@ -77,13 +77,13 @@ export class AssetHome { selectJsonExportButton() { cy.intercept("GET", "**/api/v1/asset/?**json=true**").as("getJsonexport"); - cy.get("#export-json-option").click(); + cy.get("#export-json-option").should("be.visible").click(); cy.wait("@getJsonexport").its("response.statusCode").should("eq", 200); } selectCsvExportButton() { cy.intercept("GET", "**/api/v1/asset/?**csv=true**").as("getCsvexport"); - cy.get("#export-csv-option").click(); + cy.get("#export-csv-option").should("be.visible").click(); cy.wait("@getCsvexport").its("response.statusCode").should("eq", 200); } diff --git a/cypress/pageobject/Facility/FacilityCreation.ts b/cypress/pageobject/Facility/FacilityCreation.ts index 9776433e523..f03fa65ce8b 100644 --- a/cypress/pageobject/Facility/FacilityCreation.ts +++ b/cypress/pageobject/Facility/FacilityCreation.ts @@ -21,7 +21,7 @@ export interface FacilityData { class FacilityPage { visitCreateFacilityPage() { cy.intercept("GET", "**/facility/create").as("getCreateFacilities"); - cy.visit("/facility/create"); + cy.awaitUrl("/facility/create"); cy.wait("@getCreateFacilities") .its("response.statusCode") .should("eq", 200); @@ -44,8 +44,7 @@ class FacilityPage { } selectWard(ward: string) { - cy.get("div#ward button").click(); - cy.get("[role='option']").contains(ward).click(); + advanceFilters.selectWard(ward); } typeFacilityAddress(address: string, clearBeforeTyping: boolean = false) { @@ -56,13 +55,24 @@ class FacilityPage { phoneNumber: string, clearBeforeTyping: boolean = false, ) { - cy.typeIntoField("#phone_number", phoneNumber, { clearBeforeTyping }); + cy.typeIntoField("#phone_number", phoneNumber, { + clearBeforeTyping, + skipVerification: true, + }); } clickSaveFacilityButton() { cy.verifyAndClickElement("#submit", "Save Facility"); } + interceptFacility() { + cy.intercept("POST", "**/api/v1/facility/").as("postFacility"); + } + + verifyErrorFacility() { + cy.wait("@postFacility").its("response.statusCode").should("eq", 403); + } + verifyFacilityCreatedNotification() { cy.verifyNotification("Facility added successfully"); cy.closeNotification(); @@ -159,8 +169,7 @@ class FacilityPage { cy.get("#facility-location-button").click(); cy.wait("@mapApi").its("response.statusCode").should("eq", 200); cy.get("input#pac-input").type(location).type("{enter}"); - cy.wait(2000); - cy.get("div#map-close").click(); + cy.get("div#map-close").should("be.visible").click(); } fillMiddleWareAddress(url: string) { @@ -202,21 +211,27 @@ class FacilityPage { cy.url().should("include", "/assets?facility="); } + interceptManageInventoryItem() { + cy.intercept("GET", "/api/v1/items/**").as("getItems"); + } + clickManageInventory() { cy.contains("Manage Inventory").click(); } + verifyManageInventoryItem() { + cy.wait("@getItems").its("response.statusCode").should("eq", 200); + } + fillInventoryDetails(name: string, status: string, quantity: string) { - cy.wait(2000); - cy.get("div#id").click(); - cy.get("div#id ul li").contains(name).click(); cy.get("div#isIncoming").click(); cy.get("div#isIncoming ul li").contains(status).click(); + cy.get("div#id").click(); + cy.get("div#id ul li").contains(name).click(); cy.get("[name='quantity']").type(quantity); } fillInventoryMinimumDetails(name: string, quantity: string) { - cy.wait(2000); cy.get("div#id").click(); cy.get("div#id ul li").contains(name).click(); cy.get("[name='quantity']").type(quantity); @@ -262,39 +277,12 @@ class FacilityPage { .should("eq", 201); } - getStateElement() { - return cy.get("#state"); - } - - getDistrictElement() { - return cy.get("#district"); - } - selectStateOnPincode(stateName: string) { - this.getStateElement() - .scrollIntoView() - .wait(2000) - .should("be.visible") - .then(($element) => { - const text = $element.text(); - if (!text.includes(stateName)) { - this.getStateElement().click(); - cy.get("li[role=option]").contains(stateName).click(); - } - }); + advanceFilters.selectState(stateName); } selectDistrictOnPincode(districtName: string) { - this.getDistrictElement().as("district").scrollIntoView().wait(2000); - cy.get("@district") - .should("be.visible") - .then(($element) => { - const text = $element.text(); - if (!text.includes(districtName)) { - this.getDistrictElement().click(); - cy.get("li[role=option]").contains(districtName).click(); - } - }); + advanceFilters.selectDistrict(districtName); } verifyPpeQuantity(text: string) { @@ -317,10 +305,20 @@ class FacilityPage { cy.get(badgeClass).contains(text).should("exist"); } - clickAddMinimumQuanitity() { + interceptMinimumQuantity() { + cy.intercept("GET", "**/api/v1/facility/*/min_quantity/**").as( + "getMinQuantity", + ); + } + + clickAddMinimumQuantity() { cy.get("#add-minimum-quantity").click(); } + verifyMinimumQuantity() { + cy.wait("@getMinQuantity").its("response.statusCode").should("eq", 200); + } + clickUpdateMinimumQuantity() { cy.get("#update-minimum-quantity").first().click(); } diff --git a/cypress/pageobject/Hcx/HcxClaims.ts b/cypress/pageobject/Hcx/HcxClaims.ts index b93862e6d13..883303d1af6 100644 --- a/cypress/pageobject/Hcx/HcxClaims.ts +++ b/cypress/pageobject/Hcx/HcxClaims.ts @@ -3,7 +3,7 @@ export class HcxClaims { cy.get("#select-insurance-policy", { timeout: 10000 }) .should("be.visible") .and("not.be.disabled"); - cy.clickAndSelectOption("#select-insurance-policy", policy); + cy.clickAndSelectOption("#select-insurance-policy", policy, true); } verifyPolicyEligibility() { diff --git a/cypress/pageobject/Patient/PatientConsultation.ts b/cypress/pageobject/Patient/PatientConsultation.ts index edd8ae135a4..1306432bd03 100644 --- a/cypress/pageobject/Patient/PatientConsultation.ts +++ b/cypress/pageobject/Patient/PatientConsultation.ts @@ -1,6 +1,5 @@ export class PatientConsultationPage { selectConsultationStatus(status: string) { - cy.wait(5000); cy.get("#route_to_facility").scrollIntoView(); cy.get("#route_to_facility").should("be.visible"); cy.clickAndSelectOption("#route_to_facility", status); @@ -66,7 +65,7 @@ export class PatientConsultationPage { } clickPatientDetails() { - cy.verifyAndClickElement("#consultationpage-header", "Patient Details"); + cy.verifyAndClickElement("#patient-details", "Patient Details"); } typePatientIllnessHistory(history: string) { @@ -110,7 +109,14 @@ export class PatientConsultationPage { "#consultation-buttons", "Edit Consultation Details", ); - cy.wait(3000); + } + + interceptConsultation() { + cy.intercept("GET", "**/api/v1/consultation/*").as("getConsultation"); + } + + verifyConsultation() { + cy.wait("@getConsultation").its("response.statusCode").should("eq", 200); } interceptPatientDetailsAPI(): void { diff --git a/cypress/pageobject/Patient/PatientCreation.ts b/cypress/pageobject/Patient/PatientCreation.ts index 635aac3c4d2..a74e088eeb8 100644 --- a/cypress/pageobject/Patient/PatientCreation.ts +++ b/cypress/pageobject/Patient/PatientCreation.ts @@ -3,7 +3,6 @@ import FacilityPage from "pageobject/Facility/FacilityCreation"; import PatientMedicalHistory from "./PatientMedicalHistory"; -let patient_url = ""; const facilityPage = new FacilityPage(); const patientMedicalHistory = new PatientMedicalHistory(); @@ -45,7 +44,6 @@ export class PatientPage { cy.get("#patient-search").click().type(patientName); // Type the patient name cy.intercept("GET", "**/api/v1/consultation/**").as("getPatient"); cy.get("#patient-name-list").contains(patientName).click(); - cy.wait(2000); cy.wait("@getPatient").its("response.statusCode").should("eq", 200); cy.get("#patient-name-consultation") .should("be.visible") @@ -97,7 +95,7 @@ export class PatientPage { } typePatientAge(age: string) { - cy.clickAndSelectOption("#patientAge", "Age"); + cy.clickAndSelectOption("#patientAge", "Age", true); cy.clickSubmitButton("Confirm"); cy.get("#age").clear().type(age); } @@ -140,7 +138,9 @@ export class PatientPage { } clickCancelButton() { + cy.intercept("GET", "**/api/v1/patient/*/").as("getPatient"); cy.get("#cancel").click(); + cy.wait("@getPatient"); } selectPatientGender(gender: string) { @@ -174,26 +174,20 @@ export class PatientPage { cy.url().should("include", "/patient"); } - savePatientUrl() { - cy.url().then((url) => { - patient_url = url; - }); - } - - visitPatientUrl() { - cy.visit(patient_url); - } - - visitConsultationPage() { - cy.visit(patient_url + "/consultation"); - } - clickUpdatePatient() { cy.intercept("PUT", "**/api/v1/patient/**").as("updatePatient"); cy.get("button").get("[data-testid=submit-button]").click(); cy.wait("@updatePatient").its("response.statusCode").should("eq", 200); } + interceptGetPatient() { + cy.intercept("GET", "**/api/v1/patient/*").as("getPatient"); + } + + verifyGetPatientResponse() { + cy.wait("@getPatient").its("response.statusCode").should("eq", 200); + } + clickCreateConsultationOnPatientPageWithNoConsultation() { cy.get("#create-consultation").should("be.visible").click(); } @@ -209,7 +203,6 @@ export class PatientPage { verifyPatientDashboardDetails( gender: string, age: number, - patientName: string, phoneNumber: string, emergencyPhoneNumber: string, yearOfBirth: string, @@ -221,26 +214,28 @@ export class PatientPage { isPostPartum = false, ) { cy.url().should("include", "/facility/"); - cy.get("[data-testid=patient-dashboard]").then(($dashboard) => { - expect($dashboard).to.contain(gender); - expect($dashboard).to.contain(age); - expect($dashboard).to.contain(patientName); - expect($dashboard).to.contain(phoneNumber); - expect($dashboard).to.contain(emergencyPhoneNumber); - //expect($dashboard).to.contain(yearOfBirth); //Commented out because new proposed UI does not have DOB. Can change later. - expect($dashboard).to.contain(bloodGroup); - expect($dashboard).to.contain(occupation); - socioeconomicStatus && expect($dashboard).to.contain(socioeconomicStatus); - domesticHealthcareSupport && - expect($dashboard).to.contain(domesticHealthcareSupport); - - if (isAntenatal) { - expect($dashboard).to.contain("Antenatal"); - } - if (isPostPartum) { - expect($dashboard).to.contain("Post-partum"); - } - }); + cy.get("[data-testid=patient-dashboard]") + .should("be.visible") + .then(($dashboard) => { + expect($dashboard).to.contain(gender); + expect($dashboard).to.contain(age); + expect($dashboard).to.contain(phoneNumber); + expect($dashboard).to.contain(emergencyPhoneNumber); + expect($dashboard).to.contain(yearOfBirth); + expect($dashboard).to.contain(bloodGroup); + expect($dashboard).to.contain(occupation); + socioeconomicStatus && + expect($dashboard).to.contain(socioeconomicStatus); + domesticHealthcareSupport && + expect($dashboard).to.contain(domesticHealthcareSupport); + + if (isAntenatal) { + expect($dashboard).to.contain("Antenatal"); + } + if (isPostPartum) { + expect($dashboard).to.contain("Post-partum"); + } + }); } verifyPatientLocationDetails( @@ -262,10 +257,6 @@ export class PatientPage { }); } - visitUpdatePatientUrl() { - cy.visit(patient_url + "/update"); - } - clickPatientUpdateDetails() { cy.verifyAndClickElement("#update-patient-details", "Edit Profile"); } diff --git a/cypress/pageobject/Patient/PatientDischarge.ts b/cypress/pageobject/Patient/PatientDischarge.ts index 70a6d550887..58805255088 100644 --- a/cypress/pageobject/Patient/PatientDischarge.ts +++ b/cypress/pageobject/Patient/PatientDischarge.ts @@ -6,7 +6,19 @@ class PatientDischarge { } selectDischargeReason(reason: string) { - cy.clickAndSelectOption("#discharge_reason", reason); + if (reason == "Recovered") { + cy.intercept("GET", "**/api/v1/consultation/*/prescriptions/*").as( + "getPrescriptions", + ); + cy.clickAndSelectOption("#discharge_reason", reason); + cy.wait("@getPrescriptions").its("response.statusCode").should("eq", 200); + } else if (reason == "Referred") { + cy.intercept("GET", "**/api/v1/getallfacilities/**").as("getFacilities"); + cy.clickAndSelectOption("#discharge_reason", reason); + cy.wait("@getFacilities").its("response.statusCode").should("eq", 200); + } else { + cy.clickAndSelectOption("#discharge_reason", reason); + } } typeDischargeNote(note: string) { @@ -24,6 +36,16 @@ class PatientDischarge { typeDoctorName(doctorName: string) { cy.get("#death_confirmed_by").type(doctorName); } + + interceptDischargePatient() { + cy.intercept("POST", "**/api/v1/consultation/*/discharge_patient/").as( + "postDischarge", + ); + } + + verifyDischargePatient() { + cy.wait("@postDischarge").its("response.statusCode").should("eq", 200); + } } export default PatientDischarge; diff --git a/cypress/pageobject/Patient/PatientDoctorNotes.ts b/cypress/pageobject/Patient/PatientDoctorNotes.ts index 157f35d47d9..f1ac6b87bc5 100644 --- a/cypress/pageobject/Patient/PatientDoctorNotes.ts +++ b/cypress/pageobject/Patient/PatientDoctorNotes.ts @@ -5,14 +5,15 @@ export class PatientDoctorNotes { } addDiscussionNotes(notes: string) { - cy.wait(2000); cy.get("#discussion_notes_textarea").scrollIntoView(); cy.get("#discussion_notes_textarea").click().type(notes); } selectNurseDiscussion() { cy.get("#patient-note-tab-Nurses").scrollIntoView(); + cy.intercept("GET", "/api/v1/patient/*/notes/*").as("getPatientNotes"); cy.get("#patient-note-tab-Nurses").click(); + cy.wait("@getPatientNotes").its("response.statusCode").should("eq", 200); } verifyDiscussionMessage(text: string) { diff --git a/cypress/pageobject/Patient/PatientFileupload.ts b/cypress/pageobject/Patient/PatientFileupload.ts index c70170a744d..140d5ca993b 100644 --- a/cypress/pageobject/Patient/PatientFileupload.ts +++ b/cypress/pageobject/Patient/PatientFileupload.ts @@ -23,9 +23,9 @@ export class PatientFileUpload { cy.wait(2000); cy.get("#start-recording").click(); cy.wait(2000); - cy.get("#stop-recording").click(); - cy.wait(1000); - cy.get("#save-recording").click(); + cy.get("#stop-recording").should("be.enabled").click(); + cy.wait(2000); + cy.get("#save-recording").should("be.enabled").click(); } clickUploadAudioFile() { diff --git a/cypress/pageobject/Patient/PatientLogupdate.ts b/cypress/pageobject/Patient/PatientLogupdate.ts index 45c1924e1a3..bcaf6695d96 100644 --- a/cypress/pageobject/Patient/PatientLogupdate.ts +++ b/cypress/pageobject/Patient/PatientLogupdate.ts @@ -2,7 +2,14 @@ class PatientLogupdate { clickLogupdate() { cy.get("#log-update").scrollIntoView(); cy.verifyAndClickElement("#log-update", "Log Update"); - cy.wait(2000); + } + + interceptConsultationBed() { + cy.intercept("GET", "**/api/v1/consultationbed/*").as("getBed"); + } + + verifyConsultationBed() { + cy.wait("@getBed").its("response.statusCode").should("eq", 200); } clickSwitchBed() { @@ -13,23 +20,44 @@ class PatientLogupdate { cy.clickAndSelectOption("#rounds_type", roundType); } + verifyRoundType(roundType: string) { + cy.get("#rounds_type", { timeout: 10000 }) + .should("be.visible") + .should("contain.text", roundType); + } + selectBed(bed: string) { cy.typeAndSelectOption("input[name='bed']", bed); + cy.intercept("POST", "**/api/v1/consultationbed/").as( + "postConsultationBed", + ); cy.get("#update-switchbed").click(); - cy.wait(2000); + cy.wait("@postConsultationBed") + .its("response.statusCode") + .should("eq", 201); } selectPatientCategory(category: string) { cy.clickAndSelectOption("#patientCategory", category); } - typePhysicalExamination(examination: string) { - cy.get("#physical_examination_info").click().type(examination); - cy.get("#physical_examination_info").should("contain", examination); + verifyPatientCategory(category: string) { + cy.get("#patientCategory", { timeout: 10000 }) + .should("be.visible") + .should("contain.text", category); + } + + typePhysicalExamination( + examination: string, + clearBeforeTyping: boolean = false, + ) { + cy.typeIntoField("#physical_examination_info", examination, { + clearBeforeTyping, + }); } - typeOtherDetails(details: string) { - cy.get("#other_details").click().type(details); + typeOtherDetails(details: string, clearBeforeTyping: boolean = false) { + cy.typeIntoField("#other_details", details, { clearBeforeTyping }); } typeAndMultiSelectSymptoms(input: string, symptoms: string[]) { @@ -42,59 +70,78 @@ class PatientLogupdate { cy.get("#add-symptom").click(); } - typeSystolic(systolic: string) { - cy.get("#systolic").click().type(systolic); + typeSystolic(systolic: string, clearBeforeTyping: boolean = false) { + cy.typeIntoField("#systolic", systolic, { clearBeforeTyping }); } - typeDiastolic(diastolic: string) { - cy.get("#diastolic").click().type(diastolic); + typeDiastolic(diastolic: string, clearBeforeTyping: boolean = false) { + cy.typeIntoField("#diastolic", diastolic, { clearBeforeTyping }); } - typePulse(pulse: string) { - cy.get("#pulse").click().type(pulse); + typePulse(pulse: string, clearBeforeTyping: boolean = false) { + cy.typeIntoField("#pulse", pulse, { clearBeforeTyping }); } - typeTemperature(temperature: string) { - cy.get("#temperature").click().type(temperature); + typeTemperature(temperature: string, clearBeforeTyping: boolean = false) { + cy.typeIntoField("#temperature", temperature, { clearBeforeTyping }); } - typeRespiratory(respiratory: string) { - cy.get("#resp").click().type(respiratory); + typeRespiratory(respiratory: string, clearBeforeTyping: boolean = false) { + cy.typeIntoField("#resp", respiratory, { clearBeforeTyping }); } - typeSpo2(spo: string) { - cy.get("#ventilator_spo2").click().type(spo); + typeSpo2(spo: string, clearBeforeTyping: boolean = false) { + cy.typeIntoField("#ventilator_spo2", spo, { clearBeforeTyping }); } selectRhythm(rhythm: string) { cy.clickAndSelectOption("#rhythm", rhythm); } - typeRhythm(rhythm: string) { - cy.get("#rhythm_detail").click().type(rhythm); + typeRhythm(rhythm: string, clearBeforeTyping: boolean = false) { + cy.typeIntoField("#rhythm_detail", rhythm, { clearBeforeTyping }); + } + + interceptDailyRounds() { + cy.intercept("GET", "**/api/v1/consultation/*/daily_rounds/*/").as( + "getDailyRounds", + ); + } + + verifyDailyRounds() { + cy.wait("@getDailyRounds").its("response.statusCode").should("eq", 200); + } + + interceptpatchDailyRounds() { + cy.intercept("PATCH", "**/api/v1/consultation/*/daily_rounds/*/").as( + "patchDailyRounds", + ); + } + + verifypatchDailyRounds() { + cy.wait("@patchDailyRounds").its("response.statusCode").should("eq", 200); } clickLogUpdateViewDetails(element: string, patientCategory: string) { cy.get(element).scrollIntoView(); cy.verifyContentPresence(element, [patientCategory]); + this.interceptDailyRounds(); cy.get(element).first().contains("View Details").click(); - cy.wait(3000); + this.verifyDailyRounds(); } clickLogUpdateUpdateLog(element: string, patientCategory: string) { cy.get(element).scrollIntoView(); cy.verifyContentPresence(element, [patientCategory]); + this.interceptDailyRounds(); cy.get(element).first().contains("Update Log").click(); - cy.wait(3000); + this.verifyDailyRounds(); } clickUpdateDetail() { + this.interceptDailyRounds(); cy.verifyAndClickElement("#consultation-preview", "Update Log"); - cy.wait(3000); - } - - clearIntoElementById(elementId) { - cy.get(elementId).click().clear(); + this.verifyDailyRounds(); } clickVitals() { @@ -106,8 +153,8 @@ class PatientLogupdate { cy.get("#bilateral_air_entry-option-false").click(); } - typeEtco2(etco2: string) { - cy.get("#etco2-range-input").type(etco2); + typeEtco2(etco2: string, clearBeforeTyping: boolean = false) { + cy.typeIntoField("#etco2-range-input", etco2, { clearBeforeTyping }); } selectOxygenSupport() { @@ -118,36 +165,48 @@ class PatientLogupdate { cy.get("#ventilator_oxygen_modality-option-NON_REBREATHING_MASK").click(); } - typeOxygenFlowRate(flowRate: string) { - cy.get("#oxygen_flow_rate-range-input").type(flowRate); + typeOxygenFlowRate(flowRate: string, clearBeforeTyping: boolean = false) { + cy.typeIntoField("#oxygen_flow_rate-range-input", flowRate, { + clearBeforeTyping, + }); } - typeVentilatorSpo2(spo2: string) { - cy.get("#ventilator_spo2-range-input").type(spo2); + typeVentilatorSpo2(spo2: string, clearBeforeTyping: boolean = false) { + cy.typeIntoField("#ventilator_spo2-range-input", spo2, { + clearBeforeTyping, + }); } selectCriticalCareSection(sectionName: string) { cy.contains("button", sectionName).click(); } - typeBloodSugar(bloodSugar: string) { - cy.get("#blood_sugar_level-range-input").type(bloodSugar); + typeBloodSugar(bloodSugar: string, clearBeforeTyping: boolean = false) { + cy.typeIntoField("#blood_sugar_level-range-input", bloodSugar, { + clearBeforeTyping, + }); } - typeInsulinDosage(insulinDosage: string) { - cy.get("#insulin_intake_dose-range-input").type(insulinDosage); + typeInsulinDosage(insulinDosage: string, clearBeforeTyping: boolean = false) { + cy.typeIntoField("#insulin_intake_dose-range-input", insulinDosage, { + clearBeforeTyping, + }); } clickGoBackConsultation() { cy.get("#back-to-consultation").click(); } - typeFluidBalance(fluid: string) { - cy.get("#dialysis_fluid_balance-range-input").type(fluid); + typeFluidBalance(fluid: string, clearBeforeTyping: boolean = false) { + cy.typeIntoField("#dialysis_fluid_balance-range-input", fluid, { + clearBeforeTyping, + }); } - typeNetBalance(netBalance: string) { - cy.get("#dialysis_net_balance-range-input").type(netBalance); + typeNetBalance(netBalance: string, clearBeforeTyping: boolean = false) { + cy.typeIntoField("#dialysis_net_balance-range-input", netBalance, { + clearBeforeTyping, + }); } } export default PatientLogupdate; diff --git a/cypress/pageobject/Patient/PatientMedicalHistory.ts b/cypress/pageobject/Patient/PatientMedicalHistory.ts index bf2296b4471..94c06790fbf 100644 --- a/cypress/pageobject/Patient/PatientMedicalHistory.ts +++ b/cypress/pageobject/Patient/PatientMedicalHistory.ts @@ -34,7 +34,7 @@ class PatientMedicalHistory { patientSymptoms7: string, ) { cy.get("a").contains("Health Profile").click(); - cy.wait(2000); + cy.url().should("include", "/health-profile"); cy.get("[data-test-id=patient-health-profile]").then(($dashboard) => { cy.url().should("include", "/facility/"); expect($dashboard).to.contain(patientPresentHealth); diff --git a/cypress/pageobject/Patient/PatientPrescription.ts b/cypress/pageobject/Patient/PatientPrescription.ts index d801b360aba..89b14efc7b7 100644 --- a/cypress/pageobject/Patient/PatientPrescription.ts +++ b/cypress/pageobject/Patient/PatientPrescription.ts @@ -61,8 +61,7 @@ export class PatientPrescription { } enterDiscontinueReason(reason: string) { - cy.wait(2000); - cy.get("#discontinuedReason").type(reason); + cy.get("#discontinuedReason").should("be.visible").type(reason); } enterAdministerDosage(dosage: string) { @@ -81,6 +80,16 @@ export class PatientPrescription { cy.clickAndSelectOption("#frequency", frequency); } + interceptPrescriptions() { + cy.intercept("GET", "**/api/v1/consultation/*/prescriptions/*").as( + "getPrescriptions", + ); + } + + verifyPrescription() { + cy.wait("@getPrescriptions").its("response.statusCode").should("eq", 200); + } + clickReturnToDashboard() { cy.verifyAndClickElement( "[data-testid='return-to-patient-dashboard']", diff --git a/cypress/pageobject/Patient/PatientTransfer.ts b/cypress/pageobject/Patient/PatientTransfer.ts index 0bdd55e9880..5ad49b40b5f 100644 --- a/cypress/pageobject/Patient/PatientTransfer.ts +++ b/cypress/pageobject/Patient/PatientTransfer.ts @@ -19,13 +19,11 @@ class PatientTransfer { clickTransferSubmitButton() { cy.get("#submit-transferpatient").click(); - cy.wait(2000); } clickConsultationCancelButton() { cy.get("#cancel").scrollIntoView(); cy.get("#cancel").click(); - cy.wait(2000); } clickAllowPatientTransferButton() { diff --git a/cypress/pageobject/Users/ManageUserPage.ts b/cypress/pageobject/Users/ManageUserPage.ts index 24c056a70eb..027357a0321 100644 --- a/cypress/pageobject/Users/ManageUserPage.ts +++ b/cypress/pageobject/Users/ManageUserPage.ts @@ -8,7 +8,9 @@ export class ManageUserPage { } selectSkillFromDropdown(skill: string) { + cy.intercept("GET", "/api/v1/skill/*").as("getSkills"); cy.typeAndSelectOption("input[name='skill']", skill); + cy.wait("@getSkills").its("response.statusCode").should("eq", 200); } assertLinkedFacility(facilityName: string) { @@ -213,6 +215,14 @@ export class ManageUserPage { cy.get("#facility-patients").click(); } + interceptLinkedSkillTab() { + cy.intercept("GET", "**/api/v1/users/*/skill").as("getUserSkill"); + } + + verifyLinkedSkillResponse() { + cy.wait("@getUserSkill").its("response.statusCode").should("eq", 200); + } + clickLinkedSkillTab() { cy.get("#skills").click(); } @@ -361,9 +371,15 @@ export class ManageUserPage { 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); } + interceptAddSkill() { + cy.intercept("GET", "**/api/v1/users/*/skill").as("getUserSkills"); + } + + verifyAddSkillResponse() { + cy.wait("@getUserSkills").its("response.statusCode").should("eq", 200); + } assertSkillInAlreadyLinkedSkills(skillName: string) { cy.get("#already-linked-skills") .contains(skillName) diff --git a/cypress/pageobject/Users/UserCreation.ts b/cypress/pageobject/Users/UserCreation.ts index 26eaa088e23..527cd82fa1e 100644 --- a/cypress/pageobject/Users/UserCreation.ts +++ b/cypress/pageobject/Users/UserCreation.ts @@ -48,4 +48,12 @@ export class UserCreationPage { clickSaveUserButton() { cy.clickSubmitButton("Submit"); } + + interceptCreateUser() { + cy.intercept("POST", "/api/v1/users/add_user/").as("createUser"); + } + + verifyCreateUser() { + cy.wait("@createUser").its("response.statusCode").should("eq", 201); + } } diff --git a/cypress/pageobject/Users/UserProfilePage.ts b/cypress/pageobject/Users/UserProfilePage.ts index 882be0b7b9b..50959bb7cf7 100644 --- a/cypress/pageobject/Users/UserProfilePage.ts +++ b/cypress/pageobject/Users/UserProfilePage.ts @@ -11,6 +11,14 @@ export default class UserProfilePage { cy.get("#video_connect_link").click().clear().type(link); } + interceptUpdateUsers() { + cy.intercept("PATCH", "/api/v1/users/*").as("updateUser"); + } + + verifyUpdateUsersResponse() { + cy.wait("@updateUser").its("response.statusCode").should("eq", 200); + } + clickUpdateButton() { cy.clickSubmitButton("Update"); } diff --git a/cypress/pageobject/utils/advanceFilterHelpers.ts b/cypress/pageobject/utils/advanceFilterHelpers.ts index 22925fc2c23..14e3ab41bda 100644 --- a/cypress/pageobject/utils/advanceFilterHelpers.ts +++ b/cypress/pageobject/utils/advanceFilterHelpers.ts @@ -4,17 +4,25 @@ export const advanceFilters = { }, selectState(state: string) { + cy.wait(1000); cy.clickAndSelectOption("#state", state); }, selectDistrict(district: string) { + cy.wait(1000); cy.clickAndSelectOption("#district", district); }, selectLocalBody(localBody: string) { + cy.wait(1000); cy.clickAndSelectOption("#local_body", localBody); }, + selectWard(ward: string) { + cy.wait(1000); + cy.clickAndSelectOption("#ward", ward); + }, + applySelectedFilter() { cy.verifyAndClickElement("#apply-filter", "Apply"); }, diff --git a/cypress/pageobject/utils/constants.ts b/cypress/pageobject/utils/constants.ts index 90baf3b6d4b..e14e3720231 100644 --- a/cypress/pageobject/utils/constants.ts +++ b/cypress/pageobject/utils/constants.ts @@ -1,7 +1,17 @@ -function generatePhoneNumber(): string { +function unbiasedRandom(max: number): number { const array = new Uint32Array(1); - window.crypto.getRandomValues(array); - const randomNum = (array[0] % 900000000) + 100000000; + let randomValue; + + do { + window.crypto.getRandomValues(array); + randomValue = array[0]; + } while (randomValue > Math.floor(0xffffffff / max) * max); + + return randomValue % max; +} + +function generatePhoneNumber(): string { + const randomNum = unbiasedRandom(900000000) + 100000000; // Ensure 9-digit range return "9" + randomNum.toString(); } @@ -31,9 +41,9 @@ function generateFacilityName(): string { "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 + () => unbiasedRandom(100), // Numeric IDs + () => `Zone-${unbiasedRandom(10)}`, // Zone IDs + () => `Block-${String.fromCharCode(65 + unbiasedRandom(26))}`, // Alphabetic Blocks ]; const suffixes = [ "Meta", @@ -46,21 +56,18 @@ function generateFacilityName(): string { "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)]; + const randomPrefix = prefixes[unbiasedRandom(prefixes.length)]; + const randomLocation = locations[unbiasedRandom(locations.length)]; + const randomIdentifier = identifiers[unbiasedRandom(identifiers.length)](); + const randomSuffix = suffixes[unbiasedRandom(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)]; + return formats[unbiasedRandom(formats.length)]; } function generateRandomAddress(multiline: boolean = false): string { @@ -89,17 +96,14 @@ function generateRandomAddress(multiline: boolean = false): string { ]; const districts = ["Kochi", "Ernakulam"]; const states = ["Kerala"]; - const pincode = Math.floor(682000 + Math.random() * 1000).toString(); // Generate random pincodes in the 682XXX range. + const pincode = (682000 + unbiasedRandom(1000)).toString(); - const randomLocality = - localities[Math.floor(Math.random() * localities.length)]; + const randomLocality = localities[unbiasedRandom(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)]; + neighborhoods[unbiasedRandom(neighborhoods.length)]; + const randomDistrict = districts[unbiasedRandom(districts.length)]; + const randomState = states[unbiasedRandom(states.length)]; - // Create address components const addressParts = [ randomNeighborhood, randomLocality, @@ -108,15 +112,65 @@ function generateRandomAddress(multiline: boolean = false): string { `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(", "); } +function generatePatientName(): string { + const firstNames = [ + "John", + "Jane", + "Michael", + "Sarah", + "David", + "Emma", + "James", + "Olivia", + "Robert", + "Sophia", + "William", + "Isabella", + "Benjamin", + "Mia", + "Daniel", + "Charlotte", + "Lucas", + "Amelia", + "Ethan", + "Harper", + ]; + const lastNames = [ + "Smith", + "Johnson", + "Williams", + "Brown", + "Jones", + "Miller", + "Davis", + "Garcia", + "Rodriguez", + "Wilson", + "Martinez", + "Hernandez", + "Lopez", + "Gonzalez", + "Perez", + "Taylor", + "Anderson", + "Thomas", + "Jackson", + "White", + ]; + + const randomFirstName = firstNames[unbiasedRandom(firstNames.length)]; + const randomLastName = lastNames[unbiasedRandom(lastNames.length)]; + + return `${randomFirstName} ${randomLastName}`; +} + export { generatePhoneNumber, generateEmergencyPhoneNumber, generateFacilityName, generateRandomAddress, + generatePatientName, }; diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index f5bbcf42290..54bc3be2666 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -133,12 +133,12 @@ Cypress.Commands.add("clickCancelButton", (buttonText = "Cancel") => { Cypress.Commands.add( "typeAndSelectOption", - (element: string, referance: string) => { + (element: string, reference: string) => { cy.get(element) .click() - .type(referance) + .type(reference) .then(() => { - cy.get("[role='option']").contains(referance).click(); + cy.get("[role='option']").contains(reference).click(); }); }, ); @@ -175,11 +175,17 @@ Cypress.Commands.add( Cypress.Commands.add( "clickAndSelectOption", - (element: string, reference: string) => { + (element: string, reference: string, skipVerification: boolean = false) => { cy.get(element) .click() .then(() => { cy.get("[role='option']").contains(reference).click(); + }) + .then(() => { + // Skip verification if skipVerification is true + if (!skipVerification) { + cy.get(element).should("contain", reference); + } }); }, ); @@ -247,15 +253,20 @@ Cypress.Commands.add( ( selector: string, value: string, - options: { clearBeforeTyping?: boolean } = {}, + options: { clearBeforeTyping?: boolean; skipVerification?: boolean } = {}, ) => { - const { clearBeforeTyping = false } = options; + const { clearBeforeTyping = false, skipVerification = false } = options; const inputField = cy.get(selector); if (clearBeforeTyping) { - inputField.clear(); // Clear the input field + inputField.clear(); // Clear the input field if specified } - inputField.click().type(value); // Click and type the new value + inputField.scrollIntoView().should("be.visible").click().type(value); + + // Conditionally skip verification based on the skipVerification flag + if (!skipVerification) { + inputField.should("have.value", value); // Verify the value if skipVerification is false + } }, ); diff --git a/cypress/support/index.ts b/cypress/support/index.ts index fa01326698c..59620bf8a6d 100644 --- a/cypress/support/index.ts +++ b/cypress/support/index.ts @@ -34,6 +34,7 @@ declare global { clickAndSelectOption( element: string, reference: string, + skipVerification?: boolean, ): Chainable; verifyAndClickElement( element: string, @@ -49,7 +50,7 @@ declare global { typeIntoField( selector: string, value: string, - options?: { clearBeforeTyping?: boolean }, + options?: { clearBeforeTyping?: boolean; skipVerification?: boolean }, ): Chainable; } } diff --git a/package-lock.json b/package-lock.json index 94a84d3d179..8b5bb49563a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,8 +27,8 @@ "@radix-ui/react-scroll-area": "^1.2.0", "@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", + "@radix-ui/react-tooltip": "^1.1.6", + "@sentry/browser": "^8.45.1", "@tanstack/react-query": "^5.62.3", "@tanstack/react-query-devtools": "^5.62.7", "@yudiel/react-qr-scanner": "^2.0.8", @@ -40,7 +40,7 @@ "clsx": "^2.1.1", "cmdk": "^1.0.4", "cross-env": "^7.0.3", - "cypress": "^13.15.2", + "cypress": "^13.17.0", "dayjs": "^1.11.13", "echarts": "^5.5.1", "echarts-for-react": "^3.0.2", @@ -4235,23 +4235,238 @@ } }, "node_modules/@radix-ui/react-tooltip": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.4.tgz", - "integrity": "sha512-QpObUH/ZlpaO4YgHSaYzrLO2VuO+ZBFFgGzjMUPwtiYnAzzNNDPJeEGRrT7qNOrWm/Jr08M1vlp+vTHtnSQ0Uw==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.6.tgz", + "integrity": "sha512-TLB5D8QLExS1uDn7+wH/bjEmRurNMTzNrtq7IjaS4kjion9NtzsTGkvR5+i7yc9q01Pi2KMM2cN3f8UG4IvvXA==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.3", "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-popper": "1.2.0", - "@radix-ui/react-portal": "1.1.2", - "@radix-ui/react-presence": "1.1.1", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-popper": "1.2.1", + "@radix-ui/react-portal": "1.1.3", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-slot": "1.1.1", "@radix-ui/react-use-controllable-state": "1.1.0", - "@radix-ui/react-visually-hidden": "1.1.0" + "@radix-ui/react-visually-hidden": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz", + "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-arrow": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.1.tgz", + "integrity": "sha512-NaVpZfmv8SKeZbn4ijN2V3jlHA9ngBG16VnIIm22nUR0Yk8KUALyBxT3KYEUnNuch9sTE8UTsS3whzBgKOL30w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz", + "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.3.tgz", + "integrity": "sha512-onrWn/72lQoEucDmJnr8uczSNTujT0vJnA/X5+3AkChVPowr8n1yvIKIabhWyMQeMvvmdpsvcyDqx3X1LEXCPg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-escape-keydown": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-popper": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.1.tgz", + "integrity": "sha512-3kn5Me69L+jv82EKRuQCXdYyf1DqHwD2U/sxoNgBGCB7K9TRc3bQamQ+5EPM9EvyPdli0W41sROd+ZU1dTCztw==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-rect": "1.1.0", + "@radix-ui/react-use-size": "1.1.0", + "@radix-ui/rect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-portal": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.3.tgz", + "integrity": "sha512-NciRqhXnGojhT93RPyDaMPfLH3ZSl4jjIFbZQ1b/vxvZEdHsBZ49wP9w8L3HzUQwep01LcWtkUvm0OVB5JAHTw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-presence": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz", + "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-primitive": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", + "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-slot": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.1.tgz", + "integrity": "sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-visually-hidden": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.1.tgz", + "integrity": "sha512-vVfA2IZ9q/J+gEamvj761Oq1FpWgCDaNOOIfbPVp2MVPLEomUr5+Vf7kJGwQ24YxZSlQVar7Bes8kyTo5Dshpg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.0.1" }, "peerDependencies": { "@types/react": "*", @@ -4796,50 +5011,50 @@ ] }, "node_modules/@sentry-internal/browser-utils": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.42.0.tgz", - "integrity": "sha512-xzgRI0wglKYsPrna574w1t38aftuvo44gjOKFvPNGPnYfiW9y4m+64kUz3JFbtanvOrKPcaITpdYiB4DeJXEbA==", + "version": "8.45.1", + "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.45.1.tgz", + "integrity": "sha512-sZwtP3zAzDsjUS7WkMW5VGbvSl7hGKTMc8gAJbpEsrybMxllIP13zzMRwpeFF11RnnvbrZ/FtAeX58Mvj0jahA==", "license": "MIT", "dependencies": { - "@sentry/core": "8.42.0" + "@sentry/core": "8.45.1" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/feedback": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.42.0.tgz", - "integrity": "sha512-dkIw5Wdukwzngg5gNJ0QcK48LyJaMAnBspqTqZ3ItR01STi6Z+6+/Bt5XgmrvDgRD+FNBinflc5zMmfdFXXhvw==", + "version": "8.45.1", + "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.45.1.tgz", + "integrity": "sha512-zCKptzki4SLnG+s8je8dgnppOKFjiiO4GVBc4fh7uL8zjNPBnxW8wK4SrPfAEKVYaHUzkKc5vixwUqcpmfLLGw==", "license": "MIT", "dependencies": { - "@sentry/core": "8.42.0" + "@sentry/core": "8.45.1" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/replay": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.42.0.tgz", - "integrity": "sha512-oNcJEBlDfXnRFYC5Mxj5fairyZHNqlnU4g8kPuztB9G5zlsyLgWfPxzcn1ixVQunth2/WZRklDi4o1ZfyHww7w==", + "version": "8.45.1", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.45.1.tgz", + "integrity": "sha512-cOA9CodNSR9+hmICDaGIDUvWiwxQxeMHk/esbjB8uAW8HG4CYTG3CTYTZmlmou7DuysfMd4JNuFmDFBj+YU5/A==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "8.42.0", - "@sentry/core": "8.42.0" + "@sentry-internal/browser-utils": "8.45.1", + "@sentry/core": "8.45.1" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/replay-canvas": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.42.0.tgz", - "integrity": "sha512-XrPErqVhPsPh/oFLVKvz7Wb+Fi2J1zCPLeZCxWqFuPWI2agRyLVu0KvqJyzSpSrRAEJC/XFzuSVILlYlXXSfgA==", + "version": "8.45.1", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.45.1.tgz", + "integrity": "sha512-qiPg6XwOwkiMMe/8Qf3EhXCqkSlSnWLlorYngIbdkV2klbWjd7vKnqkFJF4PnaS0g7kkZr7nh+MdzpyLyuj2Mw==", "license": "MIT", "dependencies": { - "@sentry-internal/replay": "8.42.0", - "@sentry/core": "8.42.0" + "@sentry-internal/replay": "8.45.1", + "@sentry/core": "8.45.1" }, "engines": { "node": ">=14.18" @@ -4898,25 +5113,25 @@ } }, "node_modules/@sentry/browser": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.42.0.tgz", - "integrity": "sha512-lStrEk609KJHwXfDrOgoYVVoFFExixHywxSExk7ZDtwj2YPv6r6Y1gogvgr7dAZj7jWzadHkxZ33l9EOSJBfug==", + "version": "8.45.1", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.45.1.tgz", + "integrity": "sha512-/KvYhQSRg8m9kotG8h9FrfXCWRlebrvdfXKjj1oE9SyZ2LmR8Ze9AcEw1qzsBsa1F1D/a5FQbUJahSoLBkaQPA==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "8.42.0", - "@sentry-internal/feedback": "8.42.0", - "@sentry-internal/replay": "8.42.0", - "@sentry-internal/replay-canvas": "8.42.0", - "@sentry/core": "8.42.0" + "@sentry-internal/browser-utils": "8.45.1", + "@sentry-internal/feedback": "8.45.1", + "@sentry-internal/replay": "8.45.1", + "@sentry-internal/replay-canvas": "8.45.1", + "@sentry/core": "8.45.1" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry/core": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.42.0.tgz", - "integrity": "sha512-ac6O3pgoIbU6rpwz6LlwW0wp3/GAHuSI0C5IsTgIY6baN8rOBnlAtG6KrHDDkGmUQ2srxkDJu9n1O6Td3cBCqw==", + "version": "8.45.1", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.45.1.tgz", + "integrity": "sha512-1fGmkr0paZshh38mD29c4CfkRkgFoYDaAGyDLoGYfTbEph/lU8RHB2HWzN93McqNdMEhl1DRRyqIasUZoPlqSA==", "license": "MIT", "engines": { "node": ">=14.18" @@ -7807,10 +8022,11 @@ "license": "MIT" }, "node_modules/cypress": { - "version": "13.15.2", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.15.2.tgz", - "integrity": "sha512-ARbnUorjcCM3XiPwgHKuqsyr5W9Qn+pIIBPaoilnoBkLdSC2oLQjV1BUpnmc7KR+b7Avah3Ly2RMFnfxr96E/A==", + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.17.0.tgz", + "integrity": "sha512-5xWkaPurwkIljojFidhw8lFScyxhtiFHl/i/3zov+1Z5CmY4t9tjIdvSXfu82Y3w7wt0uR9KkucbhkVvJZLQSA==", "hasInstallScript": true, + "license": "MIT", "dependencies": { "@cypress/request": "^3.0.6", "@cypress/xvfb": "^1.2.4", diff --git a/package.json b/package.json index e5eaf3342c9..a340f49fdac 100644 --- a/package.json +++ b/package.json @@ -66,8 +66,8 @@ "@radix-ui/react-scroll-area": "^1.2.0", "@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", + "@radix-ui/react-tooltip": "^1.1.6", + "@sentry/browser": "^8.45.1", "@tanstack/react-query": "^5.62.3", "@tanstack/react-query-devtools": "^5.62.7", "@yudiel/react-qr-scanner": "^2.0.8", @@ -79,7 +79,7 @@ "clsx": "^2.1.1", "cmdk": "^1.0.4", "cross-env": "^7.0.3", - "cypress": "^13.15.2", + "cypress": "^13.17.0", "dayjs": "^1.11.13", "echarts": "^5.5.1", "echarts-for-react": "^3.0.2", diff --git a/public/locale/en.json b/public/locale/en.json index a2a63121628..309139d66af 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -323,6 +323,7 @@ "ambulance_driver_name": "Name of ambulance driver", "ambulance_number": "Ambulance No", "ambulance_phone_number": "Phone number of Ambulance", + "and_the_status_of_request_is": "and the status of request is", "antenatal": "Antenatal", "any_id": "Enter any ID linked with your ABHA number", "any_id_description": "Currently we support: Aadhaar Number / Mobile Number", @@ -550,6 +551,7 @@ "contribute_github": "Contribute on Github", "copied_to_clipboard": "Copied to clipboard", "copilot_thinking": "Copilot is thinking...", + "copy_phone_number": "Copy Phone Number", "could_not_autofill": "We could not autofill any fields from what you said", "countries_travelled": "Countries travelled", "covid_19_cat_gov": "Covid_19 Clinical Category as per Govt. of Kerala guideline (A/B/C)", @@ -1215,6 +1217,8 @@ "provisional": "Provisional", "qualification": "Qualification", "qualification_required": "Qualification is required", + "quantity_approved": "QUANTITY APPROVED", + "quantity_requested": "Quantity Requested", "raise_consent_request": "Raise a consent request to fetch patient records over ABDM", "ration_card__APL": "APL", "ration_card__BPL": "BPL", @@ -1268,6 +1272,7 @@ "reset_password_note_self": "Enter your current password, then create and confirm your new password", "resource": "Resource", "resource_approving_facility": "Resource approving facility", + "resource_details": "Resource details", "resource_origin_facility": "Origin Facility", "resource_request": "Resource Request", "resource_status": "Resource Status", @@ -1409,7 +1414,9 @@ "target_dosage": "Target Dosage", "test_type": "Type of test done", "tested_on": "Tested on", + "the_request_for_resources_placed_by_yourself_is": "The request for resource (details below) placed by yourself is", "third_party_software_licenses": "Third Party Software Licenses", + "title_of_request": "Title of Request", "titrate_dosage": "Titrate Dosage", "to_be_conducted": "To be conducted", "total_amount": "Total Amount", diff --git a/src/Utils/request/uploadFile.ts b/src/Utils/request/uploadFile.ts index 005eeaf92aa..ea603e1754f 100644 --- a/src/Utils/request/uploadFile.ts +++ b/src/Utils/request/uploadFile.ts @@ -3,7 +3,7 @@ import { Dispatch, SetStateAction } from "react"; import * as Notification from "@/Utils/Notifications"; import { handleUploadPercentage } from "@/Utils/request/utils"; -const uploadFile = ( +const uploadFile = async ( url: string, file: File | FormData, reqMethod: string, @@ -11,41 +11,52 @@ const uploadFile = ( onLoad: (xhr: XMLHttpRequest) => void, setUploadPercent: Dispatch> | null, onError: () => void, -) => { - const xhr = new XMLHttpRequest(); - xhr.open(reqMethod, url); +): Promise => { + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open(reqMethod, url); - Object.entries(headers).forEach(([key, value]) => { - xhr.setRequestHeader(key, value); - }); + Object.entries(headers).forEach(([key, value]) => { + xhr.setRequestHeader(key, value); + }); - xhr.onload = () => { - onLoad(xhr); - if (400 <= xhr.status && xhr.status <= 499) { - const error = JSON.parse(xhr.responseText); - if (typeof error === "object" && !Array.isArray(error)) { - Object.values(error).forEach((msg) => { - Notification.Error({ msg: msg || "Something went wrong!" }); - }); + xhr.onload = () => { + onLoad(xhr); + if (400 <= xhr.status && xhr.status <= 499) { + let error; + try { + error = JSON.parse(xhr.responseText); + } catch { + error = xhr.responseText; + } + if (typeof error === "object" && !Array.isArray(error)) { + Object.values(error).forEach((msg) => { + Notification.Error({ msg: msg || "Something went wrong!" }); + }); + } else { + Notification.Error({ msg: error || "Something went wrong!" }); + } + reject(new Error("Client error")); } else { - Notification.Error({ msg: error || "Something went wrong!" }); + resolve(); } + }; + + if (setUploadPercent != null) { + xhr.upload.onprogress = (event: ProgressEvent) => { + handleUploadPercentage(event, setUploadPercent); + }; } - }; - if (setUploadPercent != null) { - xhr.upload.onprogress = (event: ProgressEvent) => { - handleUploadPercentage(event, setUploadPercent); + xhr.onerror = () => { + Notification.Error({ + msg: "Network Failure. Please check your internet connectivity.", + }); + onError(); + reject(new Error("Network error")); }; - } - xhr.onerror = () => { - Notification.Error({ - msg: "Network Failure. Please check your internet connectivity.", - }); - onError(); - }; - xhr.send(file); + xhr.send(file); + }); }; - export default uploadFile; diff --git a/src/Utils/utils.ts b/src/Utils/utils.ts index 5588e048bd2..f9e0e14577a 100644 --- a/src/Utils/utils.ts +++ b/src/Utils/utils.ts @@ -3,6 +3,7 @@ import { PatientModel } from "@/components/Patient/models"; import { AREACODES, IN_LANDLINE_AREA_CODES } from "@/common/constants"; import phoneCodesJson from "@/common/static/countryPhoneAndFlags.json"; +import * as Notification from "@/Utils/Notifications"; import dayjs from "@/Utils/dayjs"; interface ApacheParams { @@ -561,3 +562,12 @@ export function omitBy>( Object.entries(obj).filter(([_, value]) => !predicate(value)), ) as Partial; } + +export const copyToClipboard = async (content: string) => { + try { + await navigator.clipboard.writeText(content); + Notification.Success({ msg: "Copied to clipboard" }); + } catch (err) { + Notification.Error({ msg: "Copying is not allowed" }); + } +}; diff --git a/src/components/Common/AvatarEditModal.tsx b/src/components/Common/AvatarEditModal.tsx index bcc61819fde..dc044264c4d 100644 --- a/src/components/Common/AvatarEditModal.tsx +++ b/src/components/Common/AvatarEditModal.tsx @@ -114,20 +114,25 @@ const AvatarEditModal = ({ }; const uploadAvatar = async () => { - if (!selectedFile) { - closeModal(); - return; - } + try { + if (!selectedFile) { + closeModal(); + return; + } - setIsProcessing(true); - setIsCaptureImgBeingUploaded(true); - await handleUpload(selectedFile, () => { - setSelectedFile(undefined); - setPreview(undefined); - setPreviewImage(null); + setIsProcessing(true); + setIsCaptureImgBeingUploaded(true); + await handleUpload(selectedFile, () => { + setSelectedFile(undefined); + setPreview(undefined); + setPreviewImage(null); + setIsCaptureImgBeingUploaded(false); + setIsProcessing(false); + }); + } finally { setIsCaptureImgBeingUploaded(false); setIsProcessing(false); - }); + } }; const deleteAvatar = async () => { diff --git a/src/components/Facility/DoctorVideoSlideover.tsx b/src/components/Facility/DoctorVideoSlideover.tsx index 61c7a63c17b..98058fd4bfb 100644 --- a/src/components/Facility/DoctorVideoSlideover.tsx +++ b/src/components/Facility/DoctorVideoSlideover.tsx @@ -1,4 +1,5 @@ -import React, { useState } from "react"; +import { useState } from "react"; +import { useTranslation } from "react-i18next"; import CareIcon, { IconName } from "@/CAREUI/icons/CareIcon"; import SlideOver from "@/CAREUI/interactive/SlideOver"; @@ -17,6 +18,7 @@ import routes from "@/Utils/request/api"; import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { classNames, + copyToClipboard, formatName, isUserOnline, relativeTime, @@ -238,6 +240,9 @@ function UserListItem({ user }: { user: UserAnnotatedWithGroup }) { } } + const { t } = useTranslation(); + const [copied, setCopied] = useState(false); + return (
{ + onClick={(e) => { e.stopPropagation(); - await navigator.clipboard.writeText( - user?.alt_phone_number || "", - ); + copyToClipboard(user?.alt_phone_number || ""); + setCopied(true); + setTimeout(() => setCopied(false), 2500); }} > - Copy Phone number + {t("copy_phone_number")} - + {user.alt_phone_number} diff --git a/src/components/Resource/ResourceBoard.tsx b/src/components/Resource/ResourceBoard.tsx index 1f8ccafcb5d..39b6f5184e5 100644 --- a/src/components/Resource/ResourceBoard.tsx +++ b/src/components/Resource/ResourceBoard.tsx @@ -93,7 +93,11 @@ export default function BoardView() { currentTab={boardFilter !== ACTIVE ? 1 : 0} />
- diff --git a/src/components/Resource/ResourceDetails.tsx b/src/components/Resource/ResourceDetails.tsx index 5aefdf394a1..c7d83536c31 100644 --- a/src/components/Resource/ResourceDetails.tsx +++ b/src/components/Resource/ResourceDetails.tsx @@ -1,9 +1,12 @@ import { navigate } from "raviger"; import { useState } from "react"; +import { useTranslation } from "react-i18next"; import CareIcon from "@/CAREUI/icons/CareIcon"; +import PrintPreview from "@/CAREUI/misc/PrintPreview"; + +import { Button } from "@/components/ui/button"; -import ButtonV2 from "@/components/Common/ButtonV2"; import Loading from "@/components/Common/Loading"; import Page from "@/components/Common/Page"; import CommentSection from "@/components/Resource/ResourceCommentSection"; @@ -14,6 +17,7 @@ import { classNames, formatDateTime, formatName } from "@/Utils/utils"; export default function ResourceDetails(props: { id: string }) { const [isPrintMode, setIsPrintMode] = useState(false); + const { t } = useTranslation(); const { data, loading } = useTanStackQueryInstead(routes.getResourceDetails, { pathParams: { id: props.id }, onResponse: ({ res, data }) => { @@ -63,12 +67,15 @@ export default function ResourceDetails(props: { id: string }) {
{" "} - Date and Time:{" "} + {t("date_and_time")}:{" "} {formatDateTime(data.created_date)}
- Unique Id: + + {" "} + {t("unique_id")}:{" "} + {data.id}
@@ -96,50 +103,50 @@ export default function ResourceDetails(props: { id: string }) { data.status === "ON HOLD" ? (
- The request for resource (details below) placed by yourself is{" "} + {t("the_request_for_resources_placed_by_yourself_is")}{" "} {data.status}
) : data.status === "APPROVED" ? (
- The request for resource (details below) placed by yourself is{" "} + {t("the_request_for_resources_placed_by_yourself_is")}{" "} {data.status}
) : (
- The request for resource (details below) placed by yourself is{" "} + {t("the_request_for_resources_placed_by_yourself_is")}{" "} APPROVED - and the status of request is{" "} + {t("and_the_status_of_request_is")}{" "} {data.status}
)}
- Title of Request:{" "} + {t("title_of_request")}:{" "} {data.title || "--"}
- Reason of Request{" "} + {t("request_reason")}:{" "} {data.reason || "--"}
- Quantity Requested:{" "} + {t("quantity_requested")}:{" "} {data.requested_quantity}
- QUANTITY APPROVED:{" "} + {t("quantity_approved")}:{" "} {data.assigned_quantity}
@@ -188,186 +195,191 @@ export default function ResourceDetails(props: { id: string }) { } return ( - +
{isPrintMode ? (
-
- window.print()}> - Print - Approval Letter - - setIsPrintMode(false)} variant="secondary"> - Close - -
- {ApprovalLetter(data)} + + {ApprovalLetter(data)} +
) : ( -
-
- setIsPrintMode(true)}> - Approval - Letter - -
- {data.assigned_to_object && ( -
-
-
-

- - Assigned to: {formatName(data.assigned_to_object)} -{" "} - {data.assigned_to_object.user_type} - -

-
-
+ +
+
+
- )} -
-
-
{data.title || "--"}
- - Update Status/Details - -
- -
-
- Status: - - {data.status} - -
-
- - Category:{" "} - - {data.category || "--"} -
-
- - Subcategory:{" "} - - {data.sub_category || "--"} -
-
- - Required Quantity:{" "} - - {data.requested_quantity || "--"} -
-
- - Contact person at the current facility:{" "} - - {data.refering_facility_contact_name || "--"} -
-
- - Approved Quantity:{" "} - - {data.assigned_quantity} + {data.assigned_to_object && ( +
+
+
+

+ + Assigned to: {formatName(data.assigned_to_object)} -{" "} + {data.assigned_to_object.user_type} + +

+
+
-
- - Contact person number:{" "} - - {data.refering_facility_contact_number ? ( - - {data.refering_facility_contact_number} + )} +
+ -
- - {" "} - Is emergency:{" "} - - - {" "} - {data.emergency ? "yes" : "no"} - +
-
-
Reason:
-
{data.reason || "--"}
+
+
+ + Status:{" "} + + + {data.status} + +
+
+ + Category:{" "} + + {data.category || "--"} +
+
+ + Subcategory:{" "} + + {data.sub_category || "--"} +
+
+ + Required Quantity:{" "} + + {data.requested_quantity || "--"} +
+
+ + Contact person at the current facility:{" "} + + {data.refering_facility_contact_name || "--"} +
+
+ + Approved Quantity:{" "} + + {data.assigned_quantity} +
+
+ + Contact person number:{" "} + + {data.refering_facility_contact_number ? ( + + {data.refering_facility_contact_number} + + ) : ( + "--" + )} +
+
+ + {" "} + Is emergency:{" "} + + + {" "} + {data.emergency ? "yes" : "no"} + +
+ +
+
Reason:
+
{data.reason || "--"}
+
-
-

Audit Log

+

Audit Log

-
-
-
- Created -
-
-
- {data.created_by_object && formatName(data.created_by_object)} +
+
+
+ Created
-
- {data.created_date && formatDateTime(data.created_date)} +
+
+ {data.created_by_object && + formatName(data.created_by_object)} +
+
+ {data.created_date && formatDateTime(data.created_date)} +
-
-
-
- Last Edited -
-
-
- {formatName(data.last_edited_by_object)} +
+
+ Last Edited
-
- {data.modified_date && formatDateTime(data.modified_date)} +
+
+ {formatName(data.last_edited_by_object)} +
+
+ {data.modified_date && formatDateTime(data.modified_date)} +
-
-
-
-

Origin Facility

- - {showFacilityCard(data.origin_facility_object)} -
-
-

Resource Approving Facility

+
+
+

Origin Facility

- {showFacilityCard(data.approving_facility_object)} -
- {data.assigned_facility_object && ( + {showFacilityCard(data.origin_facility_object)} +
-

Request Fulfilling Facility

+

Resource Approving Facility

- {showFacilityCard(data.assigned_facility_object)} + {showFacilityCard(data.approving_facility_object)}
- )} -
-
-

Comments

- + {data.assigned_facility_object && ( +
+

Request Fulfilling Facility

+ + {showFacilityCard(data.assigned_facility_object)} +
+ )} +
+
+

Comments

+ +
-
+ )} - +
); } diff --git a/src/components/Resource/ResourceList.tsx b/src/components/Resource/ResourceList.tsx index 2b44599f120..0175c9d63ea 100644 --- a/src/components/Resource/ResourceList.tsx +++ b/src/components/Resource/ResourceList.tsx @@ -9,7 +9,7 @@ import { Button } from "@/components/ui/button"; import { ExportButton } from "@/components/Common/Export"; import Loading from "@/components/Common/Loading"; -import Page from "@/components/Common/Page"; +import PageTitle from "@/components/Common/PageTitle"; import { ResourceModel } from "@/components/Facility/models"; import SearchInput from "@/components/Form/SearchInput"; import BadgesList from "@/components/Resource/ResourceBadges"; @@ -194,45 +194,55 @@ export default function ListView() { }; return ( - { - const { data } = await request(routes.downloadResourceRequests, { - query: { ...appliedFilters, csv: true }, - }); - return data ?? null; - }} - filenamePrefix="resource_requests" - /> - } - breadcrumbs={false} - options={ - <> -
-
- updateQuery({ [e.name]: e.value })} - placeholder={t("search_resource")} - /> -
+
+
+
+ { + const { data } = await request( + routes.downloadResourceRequests, + { + query: { ...appliedFilters, csv: true }, + }, + ); + return data ?? null; + }} + filenamePrefix="resource_requests" + /> + } + breadcrumbs={false} + /> +
+ +
+ updateQuery({ [e.name]: e.value })} + placeholder={t("search_resource")} + className="w-full md:w-60" + /> -
- advancedFilter.setShow(true)} />
- - } - > +
+
@@ -282,6 +292,6 @@ export default function ListView() { showResourceStatus={true} key={window.location.search} /> - +
); } diff --git a/src/components/Shifting/ShiftingBoard.tsx b/src/components/Shifting/ShiftingBoard.tsx index cd9f4300fd4..068820d3311 100644 --- a/src/components/Shifting/ShiftingBoard.tsx +++ b/src/components/Shifting/ShiftingBoard.tsx @@ -124,7 +124,11 @@ export default function BoardView() { />
- diff --git a/src/components/Shifting/ShiftingList.tsx b/src/components/Shifting/ShiftingList.tsx index 3bf071f1cc2..e9051b1449b 100644 --- a/src/components/Shifting/ShiftingList.tsx +++ b/src/components/Shifting/ShiftingList.tsx @@ -8,7 +8,7 @@ import { Button } from "@/components/ui/button"; import { ExportButton } from "@/components/Common/Export"; import Loading from "@/components/Common/Loading"; -import Page from "@/components/Common/Page"; +import PageTitle from "@/components/Common/PageTitle"; import SearchInput from "@/components/Form/SearchInput"; import BadgesList from "@/components/Shifting/ShiftingBadges"; import { formatFilter } from "@/components/Shifting/ShiftingCommons"; @@ -49,46 +49,52 @@ export default function ListView() { }); return ( - { - const { data } = await request(routes.downloadShiftRequests, { - query: { ...formatFilter(qParams), csv: true }, - }); - return data ?? null; - }} - filenamePrefix="shift_requests" - /> - } - breadcrumbs={false} - options={ - <> -
+
+
+
+ { + const { data } = await request(routes.downloadShiftRequests, { + query: { ...formatFilter(qParams), csv: true }, + }); + return data ?? null; + }} + filenamePrefix="shift_requests" + /> + } + breadcrumbs={false} + /> +
+
+ updateQuery({ [e.name]: e.value })} + placeholder={t("search_patient")} + className="w-full md:w-60" + /> -
- updateQuery({ [e.name]: e.value })} - placeholder={t("search_patient")} - /> -
- -
- advancedFilter.setShow(true)} />
- - } - > +
+
+
@@ -121,6 +127,6 @@ export default function ListView() { {...advancedFilter} key={window.location.search} /> - +
); } diff --git a/src/components/Users/UserAvatar.tsx b/src/components/Users/UserAvatar.tsx index 77b353846bc..9930a2e35b7 100644 --- a/src/components/Users/UserAvatar.tsx +++ b/src/components/Users/UserAvatar.tsx @@ -18,20 +18,25 @@ import useTanStackQueryInstead from "@/Utils/request/useQuery"; import { getAuthorizationHeader } from "@/Utils/request/utils"; import { formatDisplayName, sleep } from "@/Utils/utils"; -export default function UserAvatar({ username }: { username: string }) { +export default function UserAvatar({ + username, + refetchUserData, +}: { + username: string; + refetchUserData?: () => void; +}) { const { t } = useTranslation(); const [editAvatar, setEditAvatar] = useState(false); const authUser = useAuthUser(); - const { - data: userData, - loading: isLoading, - refetch: refetchUserData, - } = useTanStackQueryInstead(routes.getUserDetails, { - pathParams: { - username: username, + const { data: userData, loading: isLoading } = useTanStackQueryInstead( + routes.getUserDetails, + { + pathParams: { + username: username, + }, }, - }); + ); if (isLoading || !userData) { return ; @@ -42,7 +47,7 @@ export default function UserAvatar({ username }: { username: string }) { formData.append("profile_picture", file); const url = `${careConfig.apiUrl}/api/v1/users/${userData.username}/profile_picture/`; - uploadFile( + await uploadFile( url, formData, "POST", @@ -50,7 +55,7 @@ export default function UserAvatar({ username }: { username: string }) { async (xhr: XMLHttpRequest) => { if (xhr.status === 200) { await sleep(1000); - refetchUserData(); + refetchUserData?.(); Notification.Success({ msg: t("avatar_updated_success") }); setEditAvatar(false); } @@ -68,7 +73,7 @@ export default function UserAvatar({ username }: { username: string }) { }); if (res?.ok) { Notification.Success({ msg: "Profile picture deleted" }); - await refetchUserData(); + refetchUserData?.(); setEditAvatar(false); } else { onError();