diff --git a/cypress/e2e/assets_spec/AssetHomepage.cy.ts b/cypress/e2e/assets_spec/AssetHomepage.cy.ts index f462bda4327..57c315bb0c4 100644 --- a/cypress/e2e/assets_spec/AssetHomepage.cy.ts +++ b/cypress/e2e/assets_spec/AssetHomepage.cy.ts @@ -99,9 +99,9 @@ describe("Asset Tab", () => { it("Export asset", () => { assetPage.selectassetimportbutton(); cy.wait(2000); - assetPage.selectjsonexportbutton(); + assetPage.selectJsonExportButton(); assetPage.selectassetimportbutton(); - assetPage.selectcsvexportbutton(); + assetPage.selectCsvExportButton(); }); afterEach(() => { diff --git a/cypress/e2e/assets_spec/AssetsCreation.cy.ts b/cypress/e2e/assets_spec/AssetsCreation.cy.ts index 1bcd984a7a3..6d94108b362 100644 --- a/cypress/e2e/assets_spec/AssetsCreation.cy.ts +++ b/cypress/e2e/assets_spec/AssetsCreation.cy.ts @@ -129,7 +129,7 @@ describe("Asset", () => { "d5694af2-21e2-4a39-9bad-2fb98d9818bd", ); assetPage.clickConfigureAsset(); - assetPage.verifyAssetConfiguration(200); + assetPage.verifyAssetConfiguration(); }); it("Add an vital monitor asset and configure it", () => { diff --git a/cypress/e2e/facility_spec/FacilityLocation.cy.ts b/cypress/e2e/facility_spec/FacilityLocation.cy.ts index 113a5e3eaab..d29ee95e873 100644 --- a/cypress/e2e/facility_spec/FacilityLocation.cy.ts +++ b/cypress/e2e/facility_spec/FacilityLocation.cy.ts @@ -193,12 +193,16 @@ describe("Location Management Section", () => { facilityLocation.clickAddNewLocationButton(); facilityLocation.enterLocationName("Test Location with Beds"); facilityLocation.selectLocationType("OTHER"); - assetPage.clickassetupdatebutton(); + cy.submitButton("Add Location"); + cy.verifyNotification("Location created successfully"); + cy.closeNotification(); facilityLocation.clickManageBedButton(); facilityLocation.clickAddBedButton(); facilityLocation.enterBedName("Bed 1"); facilityLocation.selectBedType("Regular"); - assetPage.clickassetupdatebutton(); + cy.submitButton("Add Bed(s)"); + cy.verifyNotification("1 Bed created successfully"); + cy.closeNotification(); facilityLocation.loadLocationManagementPage("Dummy Shifting Center"); facilityLocation.deleteLocation("Test Location with Beds"); assetPage.clickassetupdatebutton(); diff --git a/cypress/e2e/patient_spec/PatientDoctorConnect.cy.ts b/cypress/e2e/patient_spec/PatientDoctorConnect.cy.ts new file mode 100644 index 00000000000..64d47db2cf1 --- /dev/null +++ b/cypress/e2e/patient_spec/PatientDoctorConnect.cy.ts @@ -0,0 +1,56 @@ +import { DoctorConnect } from "pageobject/Patient/PatientDoctorConnect"; +import LoginPage from "../../pageobject/Login/LoginPage"; +import { PatientPage } from "../../pageobject/Patient/PatientCreation"; + +describe("Patient Doctor Connect in consultation page", () => { + const loginPage = new LoginPage(); + const patientPage = new PatientPage(); + const doctorconnect = new DoctorConnect(); + const patientName = "Dummy Patient 11"; + const doctorUser = "Dev Doctor"; + const doctorUserNumber = "+919876543219"; + const nurseUser = "Dev Staff"; + const teleIcuUser = "Dev Doctor Two"; + + before(() => { + loginPage.loginAsDisctrictAdmin(); + cy.saveLocalStorage(); + }); + + beforeEach(() => { + cy.restoreLocalStorage(); + cy.clearLocalStorage(/filters--.+/); + cy.awaitUrl("/patients"); + }); + + it("Patient Doctor connect phone redirection and sort by filter", () => { + // click on the slideover and verify icon redirection + patientPage.visitPatient(patientName); + doctorconnect.clickDoctorConnectButton(); + // verify all the users are visible under the all section + cy.verifyContentPresence("#doctor-connect-home-doctor", [doctorUser]); + cy.verifyContentPresence("#doctor-connect-home-nurse", [nurseUser]); + cy.verifyContentPresence("#doctor-connect-remote-doctor", [teleIcuUser]); + // verify copy content button functionality + doctorconnect.CopyFunctionTrigger(); + doctorconnect.clickCopyPhoneNumber( + "#doctor-connect-home-doctor", + doctorUser, + ); + doctorconnect.verifyCopiedContent(doctorUserNumber); + // verify the whatsapp and phone number icon presence + doctorconnect.verifyIconVisible("#whatsapp-icon"); + doctorconnect.verifyIconVisible("#phone-icon"); + // sort the each datas based on user type + doctorconnect.clickUsersSortBy("Doctor"); + cy.verifyContentPresence("#doctor-connect-home-doctor", [doctorUser]); + doctorconnect.clickUsersSortBy("Nurse"); + cy.verifyContentPresence("#doctor-connect-home-nurse", [nurseUser]); + doctorconnect.clickUsersSortBy("TeleICU Doctor"); + cy.verifyContentPresence("#doctor-connect-remote-doctor", [teleIcuUser]); + }); + + afterEach(() => { + cy.saveLocalStorage(); + }); +}); diff --git a/cypress/e2e/patient_spec/PatientFileUpload.ts b/cypress/e2e/patient_spec/PatientFileUpload.ts index 9d6852d16e7..7e5a3073179 100644 --- a/cypress/e2e/patient_spec/PatientFileUpload.ts +++ b/cypress/e2e/patient_spec/PatientFileUpload.ts @@ -5,7 +5,10 @@ const loginPage = new LoginPage(); const patientPage = new PatientPage(); const patientFileUpload = new PatientFileUpload(); -function runTests(testDescription, visitPatientFileUploadSection) { +function runTests( + testDescription: string, + visitPatientFileUploadSection: () => void, +) { describe(testDescription, () => { const cypressAudioName = "cypress audio"; const cypressFileName = "cypress name"; diff --git a/cypress/e2e/patient_spec/PatientHomepage.cy.ts b/cypress/e2e/patient_spec/PatientHomepage.cy.ts index 0cf5936594d..188b6bc9457 100644 --- a/cypress/e2e/patient_spec/PatientHomepage.cy.ts +++ b/cypress/e2e/patient_spec/PatientHomepage.cy.ts @@ -4,6 +4,24 @@ import PatientHome from "../../pageobject/Patient/PatientHome"; describe("Patient Homepage present functionalities", () => { const loginPage = new LoginPage(); const patientHome = new PatientHome(); + const patientGender = "Male"; + const patientCategory = "Moderate"; + const patientMinimumAge = "18"; + const patientMaximumAge = "24"; + const patientLastAdmittedBed = "No bed assigned"; + const PatientLastConsentType = "No consents"; + const patientTelemedicinePerference = "No"; + const patientReviewStatus = "No"; + const patientMedicoStatus = "Non-Medico-Legal"; + const patientIcdDiagnosis = "1A00"; + const facilityName = "Dummy Facility 40"; + const facilityType = "Private Hospital"; + const facilityLsgBody = "Aikaranad Grama Panchayat, Ernakulam District"; + const facilityDistrict = "Ernakulam"; + const patientFromDate = "01122023"; + const patientToDate = "07122023"; + const patientFromDateBadge = "2023-12-01"; + const patientToDateBadge = "2023-12-07"; before(() => { loginPage.loginAsDisctrictAdmin(); @@ -16,6 +34,116 @@ describe("Patient Homepage present functionalities", () => { cy.awaitUrl("/patients"); }); + it("Date based advance filters applied in the patient tab", () => { + patientHome.clickPatientAdvanceFilters(); + patientHome.typePatientCreatedBeforeDate(patientFromDate); + patientHome.typePatientCreatedAfterDate(patientToDate); + patientHome.typePatientModifiedBeforeDate(patientFromDate); + patientHome.typePatientModifiedAfterDate(patientToDate); + patientHome.typePatientAdmitedBeforeDate(patientFromDate); + patientHome.typePatientAdmitedAfterDate(patientToDate); + patientHome.clickPatientFilterApply(); + patientHome.verifyTotalPatientCount("1"); + // verify the badge and clear the count + patientHome.verifyPatientCreatedBeforeDate(patientToDateBadge); + patientHome.verifyPatientCreatedAfterDate(patientFromDateBadge); + patientHome.verifyPatientModifiedBeforeDate(patientToDateBadge); + patientHome.verifyPatientModifiedAfterDate(patientFromDateBadge); + patientHome.verifyPatientAdmittedBeforeDate(patientToDateBadge); + patientHome.verifyPatientAdmittedAfterDate(patientFromDateBadge); + cy.clearAllFilters(); + patientHome.verifyTotalPatientCount("1"); + }); + + it("Facility Geography based advance filters applied in the patient tab", () => { + patientHome.clickPatientAdvanceFilters(); + patientHome.typeFacilityName(facilityName); + patientHome.selectFacilityType(facilityType); + patientHome.typeFacilityLsgBody(facilityLsgBody); + patientHome.typeFacilityDistrict(facilityDistrict); + patientHome.clickPatientFilterApply(); + patientHome.verifyTotalPatientCount("1"); + // Clear the badges and verify the patient count along with badges + patientHome.verifyFacilityNameBadgeContent(facilityName); + patientHome.verifyFacilityTypeBadgeContent(facilityType); + patientHome.verifyFacilityLsgBadgeContent(facilityLsgBody); + patientHome.verifyFacilityDistrictContent(facilityDistrict); + cy.clearAllFilters(); + patientHome.verifyTotalPatientCount("1"); + }); + + it("Patient diagnosis based advance filters applied in the patient tab", () => { + // Patient Filtering based on icd-11 data + patientHome.clickPatientAdvanceFilters(); + patientHome.selectAnyIcdDiagnosis(patientIcdDiagnosis, patientIcdDiagnosis); + patientHome.selectConfirmedIcdDiagnosis( + patientIcdDiagnosis, + patientIcdDiagnosis, + ); + patientHome.selectUnconfirmedIcdDiagnosis( + patientIcdDiagnosis, + patientIcdDiagnosis, + ); + patientHome.selectProvisionalIcdDiagnosis( + patientIcdDiagnosis, + patientIcdDiagnosis, + ); + patientHome.selectDifferentialIcdDiagnosis( + patientIcdDiagnosis, + patientIcdDiagnosis, + ); + patientHome.clickPatientFilterApply(); + patientHome.verifyTotalPatientCount("0"); + // verify the badges presence in the platform + patientHome.verifyAnyDiagnosisBadgeContent(patientIcdDiagnosis); + patientHome.verifyConfirmedDiagnosisBadgeContent(patientIcdDiagnosis); + patientHome.verifyUnconfirmedDiagnosisBadgeContent(patientIcdDiagnosis); + patientHome.verifyProvisionalDiagnosisBadgeContent(patientIcdDiagnosis); + patientHome.verifyDifferentialDiagnosisBadgeContent(patientIcdDiagnosis); + // Clear the badges and verify the patient count along with badges + cy.clearAllFilters(); + patientHome.verifyTotalPatientCount("1"); + // Apply Any and confirmed diagonsis to verify patient count 17 + patientHome.clickPatientAdvanceFilters(); + patientHome.selectAnyIcdDiagnosis(patientIcdDiagnosis, patientIcdDiagnosis); + patientHome.selectConfirmedIcdDiagnosis( + patientIcdDiagnosis, + patientIcdDiagnosis, + ); + patientHome.clickPatientFilterApply(); + patientHome.verifyTotalPatientCount("1"); + }); + + it("Patient Details based advance filters applied in the patient tab", () => { + // Patient Filtering based on patient details + patientHome.clickPatientAdvanceFilters(); + patientHome.selectPatientGenderfilter(patientGender); + patientHome.selectPatientCategoryfilter(patientCategory); + patientHome.typePatientMinimumAgeFilter(patientMinimumAge); + patientHome.typePatientMaximumAgeFilter(patientMaximumAge); + patientHome.selectPatientLastAdmittedBed(patientLastAdmittedBed); + patientHome.selectPatientLastConsentType(PatientLastConsentType); + patientHome.selectPatientTelemedicineFilter(patientTelemedicinePerference); + patientHome.selectPatientReviewFilter(patientReviewStatus); + patientHome.selectPatientMedicoFilter(patientMedicoStatus); + patientHome.clickPatientFilterApply(); + cy.get("a[data-cy='patient']").should("contain.text", "Dummy Patient"); + patientHome.verifyTotalPatientCount("1"); + // Verify the presence of badges + patientHome.verifyGenderBadgeContent(patientGender); + patientHome.verifyCategoryBadgeContent(patientCategory); + patientHome.verifyMinAgeBadgeContent(patientMinimumAge); + patientHome.verifyMaxAgeBadgeContent(patientMaximumAge); + patientHome.verifyLastAdmittedBedBadgeContent(patientLastAdmittedBed); + patientHome.verifyLastConsentTypeBadgeContent("No Consents"); + patientHome.verifyTelemedicineBadgeContent("false"); + patientHome.verifyReviewMissedBadgeContent("false"); + patientHome.verifyMedicoBadgeContent("false"); + // Clear the badges and verify the patient count along with badges + cy.clearAllFilters(); + patientHome.verifyTotalPatientCount("1"); + }); + it("Export the live patient list based on a date range", () => { patientHome.clickPatientExport(); cy.verifyNotification("Please select a seven day period"); diff --git a/cypress/e2e/sample_test_spec/SampleTestHomepage.cy.ts b/cypress/e2e/sample_test_spec/SampleTestHomepage.cy.ts index 1af1cfc5cb4..98d69ccff41 100644 --- a/cypress/e2e/sample_test_spec/SampleTestHomepage.cy.ts +++ b/cypress/e2e/sample_test_spec/SampleTestHomepage.cy.ts @@ -13,18 +13,14 @@ describe("Sample List", () => { it("Search by District name", () => { cy.intercept(/\/api\/v1\/test_sample/).as("test_sample"); cy.get("[name='district_name']").type("Test"); - cy.wait("@test_sample").then((interception) => { - expect(interception.response.statusCode).to.equal(200); - }); + cy.wait("@test_sample").its("response.statusCode").should("eq", 200); cy.url().should("include", "Test"); }); it("Search by Patient Name", () => { cy.intercept(/\/api\/v1\/test_sample/).as("test_sample"); cy.get("[name='patient_name']").type("Test"); - cy.wait("@test_sample").then((interception) => { - expect(interception.response.statusCode).to.equal(200); - }); + cy.wait("@test_sample").its("response.statusCode").should("eq", 200); cy.url().should("include", "Test"); }); diff --git a/cypress/pageobject/Asset/AssetCreation.ts b/cypress/pageobject/Asset/AssetCreation.ts index 41d3c4ca8d0..d6991e82ff0 100644 --- a/cypress/pageobject/Asset/AssetCreation.ts +++ b/cypress/pageobject/Asset/AssetCreation.ts @@ -149,10 +149,8 @@ export class AssetPage { cy.intercept(/\/api\/v1\/asset/).as("asset"); } - verifyAssetConfiguration(statusCode: number) { - cy.wait("@asset").then((interception) => { - expect(interception.response.statusCode).to.equal(statusCode); - }); + verifyAssetConfiguration() { + cy.wait("@asset").its("response.statusCode").should("eq", 200); } clickConfigureAsset() { @@ -222,22 +220,16 @@ export class AssetPage { cy.get("[data-testid=import-asset-button]").click(); } - selectjsonexportbutton() { + selectJsonExportButton() { cy.intercept("GET", "**/api/v1/asset/?**json=true**").as("getJsonexport"); cy.get("#export-json-option").click(); - cy.wait("@getJsonexport").then(({ request, response }) => { - expect(response.statusCode).to.eq(200); - expect(request.url).to.include("json=true"); - }); + cy.wait("@getJsonexport").its("response.statusCode").should("eq", 200); } - selectcsvexportbutton() { + selectCsvExportButton() { cy.intercept("GET", "**/api/v1/asset/?**csv=true**").as("getCsvexport"); cy.get("#export-csv-option").click(); - cy.wait("@getCsvexport").then(({ request, response }) => { - expect(response.statusCode).to.eq(200); - expect(request.url).to.include("csv=true"); - }); + cy.wait("@getCsvexport").its("response.statusCode").should("eq", 200); } selectImportOption() { diff --git a/cypress/pageobject/Asset/AssetFilters.ts b/cypress/pageobject/Asset/AssetFilters.ts index ac83ca97c0b..5a942b22f47 100644 --- a/cypress/pageobject/Asset/AssetFilters.ts +++ b/cypress/pageobject/Asset/AssetFilters.ts @@ -56,16 +56,16 @@ export class AssetFilters { cy.get("#close-slide-over").click(); } // Assertions - assertFacilityText(text) { + assertFacilityText(text: string) { cy.get("[data-testid=Facility]").should("contain", text); } - assertAssetClassText(text) { + assertAssetClassText(text: string) { cy.get("[data-testid='Asset Class']").should("contain", text); } - assertStatusText(text) { + assertStatusText(text: string) { cy.get("[data-testid=Status]").should("contain", text); } - assertLocationText(text) { + assertLocationText(text: string) { cy.get("[data-testid=Location]").should("contain", text); } } diff --git a/cypress/pageobject/Facility/FacilityCreation.ts b/cypress/pageobject/Facility/FacilityCreation.ts index a1676e625dd..26f387935ac 100644 --- a/cypress/pageobject/Facility/FacilityCreation.ts +++ b/cypress/pageobject/Facility/FacilityCreation.ts @@ -9,7 +9,7 @@ class FacilityPage { .should("eq", 200); } - typeFacilitySearch(facilityName) { + typeFacilitySearch(facilityName: string) { cy.get("#search").click().clear(); cy.get("#search").click().type(facilityName); } @@ -21,7 +21,7 @@ class FacilityPage { cy.get("#manage-facility-dropdown button").should("be.visible"); } - clickUpdateFacilityType(facilityType) { + clickUpdateFacilityType(facilityType: string) { cy.get("#facility_type") .click() .then(() => { @@ -225,11 +225,11 @@ class FacilityPage { } fillTriageEntryFields( - visited, - homeQuarantine, - isolation, - referred, - confirmedPositive, + visited: string, + homeQuarantine: string, + isolation: string, + referred: string, + confirmedPositive: string, ) { cy.get("#num_patients_visited").clear().click().type(visited); cy.get("#num_patients_home_quarantine") @@ -244,7 +244,7 @@ class FacilityPage { .type(confirmedPositive); } - fillEntryDate(date) { + fillEntryDate(date: string) { cy.get("#entry_date").click(); cy.get("#date-input").click().type(date); } @@ -253,13 +253,13 @@ class FacilityPage { cy.get("#edit-button").click(); } - clickButtonsMultipleTimes(selector) { + clickButtonsMultipleTimes(selector: string) { cy.get(selector).each(($button) => { cy.wrap($button).click(); }); } - verifyTriageTableContains(value) { + verifyTriageTableContains(value: string) { cy.get("#triage-table").contains(value); } @@ -430,7 +430,7 @@ class FacilityPage { return cy.get("#district"); } - selectStateOnPincode(stateName) { + selectStateOnPincode(stateName: string) { this.getStateElement() .scrollIntoView() .wait(2000) @@ -444,7 +444,7 @@ class FacilityPage { }); } - selectDistrictOnPincode(districtName) { + selectDistrictOnPincode(districtName: string) { this.getDistrictElement() .scrollIntoView() .wait(2000) diff --git a/cypress/pageobject/Facility/FacilityHome.ts b/cypress/pageobject/Facility/FacilityHome.ts index 956c374ada4..e021171ff0a 100644 --- a/cypress/pageobject/Facility/FacilityHome.ts +++ b/cypress/pageobject/Facility/FacilityHome.ts @@ -53,7 +53,7 @@ class FacilityHome { cy.get("#facility-detailspage-cns").click(); } - selectLocation(location) { + selectLocation(location: string) { cy.get("#location").click().type(location); cy.get("li[role=option]").contains(location).click(); } @@ -99,7 +99,7 @@ class FacilityHome { return cy.url(); } - verifyURLContains(searchText) { + verifyURLContains(searchText: string) { const encodedText = encodeURIComponent(searchText).replace(/%20/g, "+"); this.getURL().should("include", `search=${encodedText}`); } diff --git a/cypress/pageobject/Facility/FacilityManage.ts b/cypress/pageobject/Facility/FacilityManage.ts index 9e41d5d0290..52a432abe59 100644 --- a/cypress/pageobject/Facility/FacilityManage.ts +++ b/cypress/pageobject/Facility/FacilityManage.ts @@ -7,17 +7,17 @@ class FacilityManage { cy.get("#upload-cover-image").should("be.visible"); } - uploadCoverImage(fileName) { + uploadCoverImage(fileName: string) { cy.get("#upload-cover-image") .selectFile(`cypress/fixtures/${fileName}`, { force: true }) .wait(100); // Adjust the wait time as needed } - verifyTotalDoctorCapacity(expectedCapacity) { + verifyTotalDoctorCapacity(expectedCapacity: string) { cy.get("#facility-doctor-totalcapacity").contains(expectedCapacity); } - verifyFacilityBedCapacity(expectedCapacity) { + verifyFacilityBedCapacity(expectedCapacity: string) { cy.get("#facility-bed-capacity-details").contains(expectedCapacity); } @@ -51,15 +51,15 @@ class FacilityManage { cy.get("#middleware_address").should("be.visible"); } - clickButtonWithText(text) { + clickButtonWithText(text: string) { cy.get("button#submit").contains(text).click(); } - checkErrorMessageVisibility(text) { + checkErrorMessageVisibility(text: string) { cy.get(".error-text").contains(text).should("be.visible"); } - typeMiddlewareAddress(address) { + typeMiddlewareAddress(address: string) { cy.get("#middleware_address").click().clear().click().type(address); } @@ -67,11 +67,14 @@ class FacilityManage { cy.get("#hf_id").click().clear(); } - typeHfrId(address) { + typeHfrId(address: string) { cy.get("#hf_id").click().clear().click().type(address); } - verifySuccessMessageVisibilityAndContent(text, isRegex = false) { + verifySuccessMessageVisibilityAndContent( + text: string | RegExp, + isRegex = false, + ) { if (isRegex) { cy.get(".pnotify-text").should("be.visible").contains(text); } else { @@ -79,11 +82,11 @@ class FacilityManage { } } - verifyMiddlewareAddressValue(expectedValue) { + verifyMiddlewareAddressValue(expectedValue: string) { cy.get("#middleware_address").should("have.value", expectedValue); } - verifyHfrIdValue(expectedValue) { + verifyHfrIdValue(expectedValue: string) { cy.get("#hf_id").should("have.value", expectedValue); } diff --git a/cypress/pageobject/Patient/PatientConsultation.ts b/cypress/pageobject/Patient/PatientConsultation.ts index cc5b8e19465..71a0fbb3909 100644 --- a/cypress/pageobject/Patient/PatientConsultation.ts +++ b/cypress/pageobject/Patient/PatientConsultation.ts @@ -6,9 +6,10 @@ export class PatientConsultationPage { cy.clickAndSelectOption("#route_to_facility", status); } - typeAndMultiSelectSymptoms(input, symptoms) { + typeAndMultiSelectSymptoms(input: string, symptoms: string[]) { cy.typeAndMultiSelectOption("#additional_symptoms", input, symptoms); } + selectSymptomsDate(date: string) { cy.clickAndTypeDate("#symptoms_onset_date", date); } @@ -25,15 +26,15 @@ export class PatientConsultationPage { } selectPatientReferance(referance: string) { - cy.searchAndSelectOption("#referred_to", referance); + cy.typeAndSelectOption("#referred_to", referance); } selectBed(bedNo: string) { - cy.searchAndSelectOption("#bed", bedNo); + cy.typeAndSelectOption("#bed", bedNo); } selectPatientWard(ward: string) { - cy.searchAndSelectOption("#transferred_from_location", ward); + cy.typeAndSelectOption("#transferred_from_location", ward); } selectPatientSuggestion(suggestion: string) { @@ -48,8 +49,8 @@ export class PatientConsultationPage { cy.get("#death_confirmed_doctor").click().type(doctor); } - selectPatientDiagnosis(icdCode, statusId) { - cy.searchAndSelectOption("#icd11-search", icdCode); + selectPatientDiagnosis(icdCode: string, statusId: string) { + cy.typeAndSelectOption("#icd11-search", icdCode); cy.get("#diagnosis-list") .contains("Add as") .scrollIntoView() @@ -92,13 +93,13 @@ export class PatientConsultationPage { cy.clickAndSelectOption("#principal-diagnosis-select", diagnosis); } - verifyTextInConsultation(selector, text) { + verifyTextInConsultation(selector: string, text: string) { cy.get(selector).scrollIntoView(); cy.get(selector).contains(text).should("be.visible"); } typeReferringFacility(referringFacility: string) { - cy.searchAndSelectOption("#referred_from_facility", referringFacility); + cy.typeAndSelectOption("#referred_from_facility", referringFacility); } clickEditConsultationButton() { diff --git a/cypress/pageobject/Patient/PatientCreation.ts b/cypress/pageobject/Patient/PatientCreation.ts index e037f0888f0..a583844a632 100644 --- a/cypress/pageobject/Patient/PatientCreation.ts +++ b/cypress/pageobject/Patient/PatientCreation.ts @@ -10,7 +10,7 @@ export class PatientPage { cy.wait("@getFacilities").its("response.statusCode").should("eq", 200); } - visitPatient(patientName) { + visitPatient(patientName: string) { cy.get("#name").click().type(patientName); cy.intercept("GET", "**/api/v1/consultation/**").as("getPatient"); cy.get("#patient-name-list").contains(patientName).click(); @@ -22,7 +22,7 @@ export class PatientPage { } selectFacility(facilityName: string) { - cy.searchAndSelectOption("input[name='facilities']", facilityName); + cy.typeAndSelectOption("input[name='facilities']", facilityName); cy.submitButton("Select"); } @@ -114,7 +114,7 @@ export class PatientPage { } selectPatientOccupation(occupation: string) { - cy.searchAndSelectOption("#occupation", occupation); + cy.typeAndSelectOption("#occupation", occupation); } selectSocioeconomicStatus(value: string) { @@ -165,16 +165,16 @@ export class PatientPage { } verifyPatientDashboardDetails( - gender, - age, - patientName, - phoneNumber, - emergencyPhoneNumber, - yearOfBirth, - bloodGroup, - occupation, - socioeconomicStatus = null, - domesticHealthcareSupport = null, + gender: string, + age: number, + patientName: string, + phoneNumber: string, + emergencyPhoneNumber: string, + yearOfBirth: string, + bloodGroup: string, + occupation: string, + socioeconomicStatus: string | null = null, + domesticHealthcareSupport: string | null = null, isAntenatal = false, isPostPartum = false, ) { @@ -202,12 +202,12 @@ export class PatientPage { } verifyPatientLocationDetails( - patientAddress, - patientPincode, - patientState, - patientDistrict, - patientLocalbody, - patientWard, + patientAddress: string, + patientPincode: number, + patientState: string, + patientDistrict: string, + patientLocalbody: string, + patientWard: string, ) { cy.get("[data-testid=patient-details]").then(($dashboard) => { cy.url().should("include", "/facility/"); diff --git a/cypress/pageobject/Patient/PatientDischarge.ts b/cypress/pageobject/Patient/PatientDischarge.ts index eda6a379a3f..70a6d550887 100644 --- a/cypress/pageobject/Patient/PatientDischarge.ts +++ b/cypress/pageobject/Patient/PatientDischarge.ts @@ -14,7 +14,7 @@ class PatientDischarge { } typeReferringFacility(facility: string) { - cy.searchAndSelectOption("#facility-referredto", facility); + cy.typeAndSelectOption("#facility-referredto", facility); } clickClearButton() { diff --git a/cypress/pageobject/Patient/PatientDoctorConnect.ts b/cypress/pageobject/Patient/PatientDoctorConnect.ts new file mode 100644 index 00000000000..b8c33bb4b24 --- /dev/null +++ b/cypress/pageobject/Patient/PatientDoctorConnect.ts @@ -0,0 +1,32 @@ +export class DoctorConnect { + clickDoctorConnectButton() { + cy.get("#doctor-connect-button").scrollIntoView(); + cy.get("#doctor-connect-button").click(); + } + + CopyFunctionTrigger() { + cy.window().then((win) => { + cy.stub(win.navigator.clipboard, "writeText").as("clipboardStub"); + }); + } + + verifyCopiedContent(text: string) { + cy.get("@clipboardStub").should("be.calledWith", text); + } + + verifyIconVisible(selector: string) { + cy.get(selector).should("be.visible"); + } + + clickCopyPhoneNumber(element: string, text: string) { + cy.get(element) + .contains(text) // Find the element containing "dev doctor" + .parent() // Move up to the parent element (if necessary) + .find("#copy-phoneicon") // Find the #copy-phoneicon within that context + .click(); + } + + clickUsersSortBy(text: string) { + cy.get("#doctor-connect-filter-tabs").contains(text).click(); + } +} diff --git a/cypress/pageobject/Patient/PatientHome.ts b/cypress/pageobject/Patient/PatientHome.ts index d2f4efdc877..a69a96c3f77 100644 --- a/cypress/pageobject/Patient/PatientHome.ts +++ b/cypress/pageobject/Patient/PatientHome.ts @@ -27,11 +27,15 @@ class PatientHome { } verifyPatientExportRequest() { - cy.wait("@getPatients").then((interception) => { - expect(interception.request.url).to.include("/api/v1/patient/"); - expect(interception.request.url).to.include("&csv"); - expect(interception.response.statusCode).to.eq(200); - }); + cy.wait("@getPatients").its("response.statusCode").should("eq", 200); + } + + typePatientCreatedBeforeDate(startDate: string) { + cy.clickAndTypeDate("input[name='created_date_start']", startDate); + } + + typePatientCreatedAfterDate(endDate: string) { + cy.clickAndTypeDate("input[name='created_date_end']", endDate); } typePatientModifiedBeforeDate(startDate: string) { @@ -41,5 +45,211 @@ class PatientHome { typePatientModifiedAfterDate(endDate: string) { cy.clickAndTypeDate("input[name='modified_date_end']", endDate); } + + typePatientAdmitedBeforeDate(startDate: string) { + cy.clickAndTypeDate( + "input[name='last_consultation_encounter_date_start']", + startDate, + ); + } + + typePatientAdmitedAfterDate(endDate: string) { + cy.clickAndTypeDate( + "input[name='last_consultation_encounter_date_end']", + endDate, + ); + } + + clickPatientAdvanceFilters() { + cy.get("#advanced-filter").click(); + } + + selectPatientGenderfilter(gender: string) { + cy.clickAndSelectOption("#gender-advancefilter", gender); + } + + selectPatientCategoryfilter(category: string) { + cy.clickAndSelectOption("#category-advancefilter", category); + } + + typePatientMinimumAgeFilter(minage: string) { + cy.get("#age_min").type(minage); + } + + typePatientMaximumAgeFilter(maxage: string) { + cy.get("#age_max").type(maxage); + } + + selectPatientLastAdmittedBed(bed: string) { + cy.clickAndMultiSelectOption( + "#last_consultation_admitted_bed_type_list", + bed, + ); + } + + selectPatientLastConsentType(consent: string) { + cy.clickAndMultiSelectOption("#last_consultation__consent_types", consent); + } + + selectPatientTelemedicineFilter(telemedicine: string) { + cy.clickAndSelectOption("#telemedicine-advancefilter", telemedicine); + } + + selectPatientReviewFilter(review: string) { + cy.clickAndSelectOption("#review-advancefilter", review); + } + + selectPatientMedicoFilter(medico: string) { + cy.clickAndSelectOption("#medico-advancefilter", medico); + } + + verifyGenderBadgeContent(expectedText: string) { + cy.get("[data-testid='Gender']").should("contain", expectedText); + } + + verifyCategoryBadgeContent(expectedText: string) { + cy.get("[data-testid='Category']").should("contain", expectedText); + } + + verifyMinAgeBadgeContent(expectedText: string) { + cy.get("[data-testid='Age min']").should("contain", expectedText); + } + + verifyMaxAgeBadgeContent(expectedText: string) { + cy.get("[data-testid='Age max']").should("contain", expectedText); + } + + verifyLastAdmittedBedBadgeContent(expectedText: string) { + cy.get("[data-testid='Bed Type']").should("contain", expectedText); + } + + verifyLastConsentTypeBadgeContent(expectedText: string) { + cy.get("[data-testid='Has Consent']").should("contain", expectedText); + } + + verifyTelemedicineBadgeContent(expectedText: string) { + cy.get("[data-testid='Telemedicine']").should("contain", expectedText); + } + + verifyReviewMissedBadgeContent(expectedText: string) { + cy.get("[data-testid='Review Missed']").should("contain", expectedText); + } + + verifyMedicoBadgeContent(expectedText: string) { + cy.get("[data-testid='Is Medico-Legal Case']").should( + "contain", + expectedText, + ); + } + + verifyTotalPatientCount(count: string) { + cy.get("#total-patientcount").should("contain", count); + } + + selectAnyIcdDiagnosis(input: string, random: string) { + cy.typeAndMultiSelectOption("#diagnoses", input, random); + } + + selectConfirmedIcdDiagnosis(input: string, confirmed: string) { + cy.typeAndMultiSelectOption("#diagnoses_confirmed", input, confirmed); + } + + selectUnconfirmedIcdDiagnosis(input: string, unconfirmed: string) { + cy.typeAndMultiSelectOption("#diagnoses_unconfirmed", input, unconfirmed); + } + + selectProvisionalIcdDiagnosis(input: string, unconfirmed: string) { + cy.typeAndMultiSelectOption("#diagnoses_provisional", input, unconfirmed); + } + + selectDifferentialIcdDiagnosis(input: string, unconfirmed: string) { + cy.typeAndMultiSelectOption("#diagnoses_differential", input, unconfirmed); + } + + typeFacilityName(facilityName: string) { + cy.typeAndSelectOption("input[name='facility']", facilityName); + } + + selectFacilityType(facilityType: string) { + cy.clickAndSelectOption("#facility-type", facilityType); + } + + typeFacilityLsgBody(lsgbody: string) { + cy.typeAndSelectOption("#facility-lsgbody", lsgbody); + } + + typeFacilityDistrict(district: string) { + cy.typeAndSelectOption("#facility-district", district); + } + + verifyAnyDiagnosisBadgeContent(expectedText: string) { + cy.get("[data-testid='Diagnoses (of any verification status)']").should( + "contain", + expectedText, + ); + } + + verifyConfirmedDiagnosisBadgeContent(expectedText: string) { + cy.get("[data-testid='Confirmed Diagnoses']").should( + "contain", + expectedText, + ); + } + + verifyUnconfirmedDiagnosisBadgeContent(expectedText: string) { + cy.get("[data-testid='Unconfirmed Diagnoses']").should( + "contain", + expectedText, + ); + } + + verifyProvisionalDiagnosisBadgeContent(expectedText: string) { + cy.get("[data-testid='Provisional Diagnoses']").should( + "contain", + expectedText, + ); + } + + verifyDifferentialDiagnosisBadgeContent(expectedText: string) { + cy.get("[data-testid='Differential Diagnoses']").should( + "contain", + expectedText, + ); + } + + verifyFacilityNameBadgeContent(expectedText: string) { + cy.get("[data-testid='Facility']").should("contain", expectedText); + } + + verifyFacilityTypeBadgeContent(expectedText: string) { + cy.get("[data-testid='Facility Type']").should("contain", expectedText); + } + + verifyFacilityLsgBadgeContent(expectedText: string) { + cy.get("[data-testid='LSG Body']").should("contain", expectedText); + } + + verifyFacilityDistrictContent(expectedText: string) { + cy.get("[data-testid='District']").should("contain", expectedText); + } + + verifyPatientCreatedAfterDate(expectedText: string) { + cy.get("[data-testid='Created after']").should("contain", expectedText); + } + verifyPatientCreatedBeforeDate(expectedText: string) { + cy.get("[data-testid='Created before']").should("contain", expectedText); + } + verifyPatientModifiedAfterDate(expectedText: string) { + cy.get("[data-testid='Modified after']").should("contain", expectedText); + } + verifyPatientModifiedBeforeDate(expectedText: string) { + cy.get("[data-testid='Modified before']").should("contain", expectedText); + } + verifyPatientAdmittedBeforeDate(expectedText: string) { + cy.get("[data-testid='Admitted before']").should("contain", expectedText); + } + verifyPatientAdmittedAfterDate(expectedText: string) { + cy.get("[data-testid='Admitted after']").should("contain", expectedText); + } } export default PatientHome; diff --git a/cypress/pageobject/Patient/PatientInsurance.ts b/cypress/pageobject/Patient/PatientInsurance.ts index bdd571e9d0c..1b91d27b629 100644 --- a/cypress/pageobject/Patient/PatientInsurance.ts +++ b/cypress/pageobject/Patient/PatientInsurance.ts @@ -47,11 +47,11 @@ class PatientInsurance { } verifyPatientPolicyDetails( - subscriberId, - policyId, - insurerId, - insurerName, - isHcxEnabled, + subscriberId: string, + policyId: string, + insurerId: string, + insurerName: string, + isHcxEnabled: string, ) { cy.get("[data-testid=patient-details]").then(($dashboard) => { cy.url().should("include", "/facility/"); diff --git a/cypress/pageobject/Patient/PatientLogupdate.ts b/cypress/pageobject/Patient/PatientLogupdate.ts index add3fbb0590..857fe7dd972 100644 --- a/cypress/pageobject/Patient/PatientLogupdate.ts +++ b/cypress/pageobject/Patient/PatientLogupdate.ts @@ -14,7 +14,7 @@ class PatientLogupdate { } selectBed(bed: string) { - cy.searchAndSelectOption("input[name='bed']", bed); + cy.typeAndSelectOption("input[name='bed']", bed); cy.get("#update-switchbed").click(); cy.wait(2000); } @@ -32,7 +32,7 @@ class PatientLogupdate { cy.get("#other_details").click().type(details); } - typeAndMultiSelectSymptoms(input, symptoms) { + typeAndMultiSelectSymptoms(input: string, symptoms: string[]) { cy.typeAndMultiSelectOption("#additional_symptoms", input, symptoms); } selectSymptomsDate(date: string) { @@ -43,27 +43,27 @@ class PatientLogupdate { } typeSystolic(systolic: string) { - cy.searchAndSelectOption("#systolic", systolic); + cy.typeAndSelectOption("#systolic", systolic); } typeDiastolic(diastolic: string) { - cy.searchAndSelectOption("#diastolic", diastolic); + cy.typeAndSelectOption("#diastolic", diastolic); } typePulse(pulse: string) { - cy.searchAndSelectOption("#pulse", pulse); + cy.typeAndSelectOption("#pulse", pulse); } typeTemperature(temperature: string) { - cy.searchAndSelectOption("#temperature", temperature); + cy.typeAndSelectOption("#temperature", temperature); } typeRespiratory(respiratory: string) { - cy.searchAndSelectOption("#resp", respiratory); + cy.typeAndSelectOption("#resp", respiratory); } typeSpo2(spo: string) { - cy.searchAndSelectOption("#ventilator_spo2", spo); + cy.typeAndSelectOption("#ventilator_spo2", spo); } selectRhythm(rhythm: string) { @@ -74,14 +74,14 @@ class PatientLogupdate { cy.get("#rhythm_detail").click().type(rhythm); } - clickLogUpdateViewDetails(element, patientCategory) { + clickLogUpdateViewDetails(element: string, patientCategory: string) { cy.get(element).scrollIntoView(); cy.verifyContentPresence(element, [patientCategory]); cy.get(element).first().contains("View Details").click(); cy.wait(3000); } - clickLogUpdateUpdateLog(element, patientCategory) { + clickLogUpdateUpdateLog(element: string, patientCategory: string) { cy.get(element).scrollIntoView(); cy.verifyContentPresence(element, [patientCategory]); cy.get(element).first().contains("Update Log").click(); @@ -93,7 +93,7 @@ class PatientLogupdate { cy.wait(3000); } - clickClearButtonInElement(elementId) { + clickClearButtonInElement(elementId: string) { cy.get(elementId).find("#clear-button").click(); } diff --git a/cypress/pageobject/Patient/PatientMedicalHistory.ts b/cypress/pageobject/Patient/PatientMedicalHistory.ts index a0dbdd0131a..93fdd1b38b3 100644 --- a/cypress/pageobject/Patient/PatientMedicalHistory.ts +++ b/cypress/pageobject/Patient/PatientMedicalHistory.ts @@ -11,7 +11,7 @@ class PatientMedicalHistory { cy.get("#allergies").click().type(allergies); } - typeMedicalHistory(index, text) { + typeMedicalHistory(index: number, text: string) { cy.get(`#medical_history_check_${index}`).click(); cy.get(`#medical_history_${index}`).click().type(text); } @@ -22,16 +22,16 @@ class PatientMedicalHistory { } verifyPatientMedicalDetails( - patientPresentHealth, - patientOngoingMedication, - patientAllergies, - patientSymptoms1, - patientSymptoms2, - patientSymptoms3, - patientSymptoms4, - patientSymptoms5, - patientSymptoms6, - patientSymptoms7, + patientPresentHealth: string, + patientOngoingMedication: string, + patientAllergies: string, + patientSymptoms1: string, + patientSymptoms2: string, + patientSymptoms3: string, + patientSymptoms4: string, + patientSymptoms5: string, + patientSymptoms6: string, + patientSymptoms7: string, ) { cy.get("[data-testid=patient-details]").then(($dashboard) => { cy.url().should("include", "/facility/"); diff --git a/cypress/pageobject/Patient/PatientPrescription.ts b/cypress/pageobject/Patient/PatientPrescription.ts index 403d361e55c..d801b360aba 100644 --- a/cypress/pageobject/Patient/PatientPrescription.ts +++ b/cypress/pageobject/Patient/PatientPrescription.ts @@ -16,7 +16,7 @@ export class PatientPrescription { } selectMedicine(medicine: string) { - cy.searchAndSelectOption( + cy.typeAndSelectOption( "div#medicine_object input[placeholder='Select'][role='combobox']", medicine, ); diff --git a/cypress/pageobject/Patient/PatientTreatmentPlan.ts b/cypress/pageobject/Patient/PatientTreatmentPlan.ts index 70af5604776..0bbddbf70bc 100644 --- a/cypress/pageobject/Patient/PatientTreatmentPlan.ts +++ b/cypress/pageobject/Patient/PatientTreatmentPlan.ts @@ -4,7 +4,7 @@ class PatientTreatmentPlan { } fillTreatingPhysican(doctor: string) { - cy.searchAndSelectOption("#treating_physician", doctor); + cy.typeAndSelectOption("#treating_physician", doctor); } selectReviewAfter(time: string) { @@ -20,7 +20,7 @@ class PatientTreatmentPlan { } assignTelemedicineDoctor(doctor: string) { - cy.searchAndSelectOption("#assigned_to", doctor); + cy.typeAndSelectOption("#assigned_to", doctor); } clickAddProcedure() { diff --git a/cypress/pageobject/Resource/ResourcePage.ts b/cypress/pageobject/Resource/ResourcePage.ts index e4078fcb317..730d3dd9148 100644 --- a/cypress/pageobject/Resource/ResourcePage.ts +++ b/cypress/pageobject/Resource/ResourcePage.ts @@ -4,9 +4,9 @@ class ResourcePage { cy.get("svg.care-svg-icon__baseline.care-l-export").each(($button) => { cy.intercept(/\/api\/v1\/resource/).as("resource_download"); cy.wrap($button).click({ force: true }); - cy.wait("@resource_download").then((interception) => { - expect(interception.response.statusCode).to.equal(200); - }); + cy.wait("@resource_download") + .its("response.statusCode") + .should("eq", 200); }); } @@ -19,9 +19,7 @@ class ResourcePage { } verifyCompletedResources() { - cy.wait("@resource").then((interception) => { - expect(interception.response.statusCode).to.equal(200); - }); + cy.wait("@resource").its("response.statusCode").should("eq", 200); cy.contains("button", "Active").should("have.class", "text-primary-500"); cy.contains("button", "Completed").should("have.class", "text-white"); } @@ -31,9 +29,7 @@ class ResourcePage { } verifyActiveResources() { - cy.wait("@resource").then((interception) => { - expect(interception.response.statusCode).to.equal(200); - }); + cy.wait("@resource").its("response.statusCode").should("eq", 200); cy.contains("button", "Active").should("have.class", "text-white"); cy.contains("button", "Completed").should("have.class", "text-primary-500"); } diff --git a/cypress/pageobject/Users/ManageUserPage.ts b/cypress/pageobject/Users/ManageUserPage.ts index f3e0deca53b..efa0d90142c 100644 --- a/cypress/pageobject/Users/ManageUserPage.ts +++ b/cypress/pageobject/Users/ManageUserPage.ts @@ -1,5 +1,5 @@ export class ManageUserPage { - assertHomeFacility(expectedText) { + assertHomeFacility(expectedText: string) { cy.get("#home_facility").should("contain.text", expectedText); } @@ -7,23 +7,23 @@ export class ManageUserPage { cy.get("#facilities").click(); } - selectFacilityFromDropdown(facilityName) { - cy.searchAndSelectOption("input[name='facility']", facilityName); + selectFacilityFromDropdown(facilityName: string) { + cy.typeAndSelectOption("input[name='facility']", facilityName); } - selectSkillFromDropdown(skill) { - cy.searchAndSelectOption("input[name='skill']", skill); + selectSkillFromDropdown(skill: string) { + cy.typeAndSelectOption("input[name='skill']", skill); } clickLinkFacility() { cy.get("#link-facility").click(); } - assertLinkedFacility(facilityName) { + assertLinkedFacility(facilityName: string) { cy.get("#linked-facility-list").should("contain.text", facilityName); } - assertnotLinkedFacility(facilityName) { + assertnotLinkedFacility(facilityName: string) { cy.get("#linked-facility-list").should("not.contain", facilityName); } @@ -31,11 +31,11 @@ export class ManageUserPage { cy.get("#linked-facility-list").should("not.exist"); } - assertHomeFacilitylink(facilityName) { + assertHomeFacilitylink(facilityName: string) { cy.get("#home-facility").should("contain.text", facilityName); } - assertFacilityNotInDropdown(facilityName) { + assertFacilityNotInDropdown(facilityName: string) { cy.get("input[name='facility']").click().type(facilityName); cy.get("[role='option']").should("not.exist"); } @@ -93,12 +93,12 @@ export class ManageUserPage { cy.visit("/facility"); } - typeFacilitySearch(facilityName) { + typeFacilitySearch(facilityName: string) { cy.get("#search").click().clear(); cy.get("#search").click().type(facilityName); } - assertFacilityInCard(facilityName) { + assertFacilityInCard(facilityName: string) { cy.get("#facility-name-card").should("contain", facilityName); } @@ -117,13 +117,13 @@ export class ManageUserPage { cy.wait("@getSkills").its("response.statusCode").should("eq", 200); } - assertSkillInAlreadyLinkedSkills(skillName) { + assertSkillInAlreadyLinkedSkills(skillName: string) { cy.get("#already-linked-skills") .contains(skillName) .should("have.length", 1); } - assertSkillIndoctorconnect(skillName) { + assertSkillIndoctorconnect(skillName: string) { cy.get("#doctor-connect-home-doctor") .contains(skillName) .should("have.length", 1); @@ -137,11 +137,11 @@ export class ManageUserPage { cy.get("#unlink-skill").click(); } - assertSkillInAddedUserSkills(skillName) { + assertSkillInAddedUserSkills(skillName: string) { cy.get("#added-user-skills").should("contain", skillName); } - assertDoctorConnectVisibility(realName) { + assertDoctorConnectVisibility(realName: string) { cy.get('*[id="doctor-connect-home-doctor"]').should( "contain.text", realName, diff --git a/cypress/pageobject/Users/UserSearch.ts b/cypress/pageobject/Users/UserSearch.ts index 0c214e92706..d72c00c0de7 100644 --- a/cypress/pageobject/Users/UserSearch.ts +++ b/cypress/pageobject/Users/UserSearch.ts @@ -53,11 +53,11 @@ export class UserPage { } selectState(state: string) { - cy.searchAndSelectOption("#state input", state); + cy.typeAndSelectOption("#state input", state); } selectDistrict(district: string) { - cy.searchAndSelectOption("#district input", district); + cy.typeAndSelectOption("#district input", district); } typeInPhoneNumber(phone: string) { @@ -69,7 +69,7 @@ export class UserPage { } selectHomeFacility(facility: string) { - cy.searchAndSelectOption("input[name='home_facility']", facility); + cy.typeAndSelectOption("input[name='home_facility']", facility); } applyFilter() { diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index 86d048e5f41..da78361f6e8 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -38,8 +38,8 @@ Cypress.Commands.add("refreshApiLogin", (username, password) => { Cypress.Commands.add("loginByApi", (username, password) => { cy.log(`Logging in the user: ${username}:${password}`); cy.task("readFileMaybe", "cypress/fixtures/token.json").then( - (tkn: string) => { - const token = JSON.parse(tkn); + (tkn: unknown) => { + const token = JSON.parse(tkn as string); // Cast tkn to string if (tkn && token.access && token.username === username) { cy.request({ method: "POST", @@ -66,21 +66,6 @@ Cypress.Commands.add("loginByApi", (username, password) => { ); }); -Cypress.Commands.add( - "awaitUrl", - (url: string, disableLoginVerification = false) => { - cy.intercept(/getcurrentuser/).as("currentuser"); - cy.visit(url); - disableLoginVerification - ? cy.wait("@currentuser") - : cy.wait("@currentuser").its("response.statusCode").should("eq", 200); - }, -); - -Cypress.Commands.add("verifyNotification", (text) => { - return cy.get(".pnotify-container").should("exist").contains(text); -}); - Cypress.on("uncaught:exception", () => { // returning false here prevents Cypress from // failing the test @@ -94,19 +79,44 @@ Cypress.on("uncaught:exception", () => { * Waits until the selector finds an attached element, then yields it (wrapped). * selectorFn, if provided, is passed $(document). Don't use cy methods inside selectorFn. */ -Cypress.Commands.add("getAttached", (selector) => { +Cypress.Commands.add("getAttached", (selector: string) => { const getElement = - typeof selector === "function" ? selector : ($d) => $d.find(selector); - let $el = null; + typeof selector === "function" + ? selector + : ($d: JQuery) => + $d.find(selector) as unknown as JQuery; + + let $el: JQuery | null = null; + return cy .document() - .should(($d) => { + .should(($d: Document) => { $el = getElement(Cypress.$($d)); - expect(Cypress.dom.isDetached($el)).to.be.false; + // Ensure $el is an HTMLElement before checking if it is detached + if ($el.length && $el[0] instanceof HTMLElement) { + expect(Cypress.dom.isDetached($el[0])).to.be.false; // Access the first HTMLElement + } else { + throw new Error("Element is not an HTMLElement or is detached."); + } }) .then(() => cy.wrap($el)); }); +Cypress.Commands.add( + "awaitUrl", + (url: string, disableLoginVerification = false) => { + cy.intercept(/getcurrentuser/).as("currentuser"); + cy.visit(url); + disableLoginVerification + ? cy.wait("@currentuser") + : cy.wait("@currentuser").its("response.statusCode").should("eq", 200); + }, +); + +Cypress.Commands.add("verifyNotification", (text) => { + return cy.get(".pnotify-container").should("exist").contains(text); +}); + Cypress.Commands.add("clearAllFilters", () => { return cy.get("#clear-all-filters").click(); }); @@ -117,7 +127,7 @@ Cypress.Commands.add("submitButton", (buttonText = "Submit") => { }); Cypress.Commands.add( - "searchAndSelectOption", + "typeAndSelectOption", (element: string, referance: string) => { cy.get(element) .click() diff --git a/cypress/support/index.ts b/cypress/support/index.ts index d660246324f..b2895871872 100644 --- a/cypress/support/index.ts +++ b/cypress/support/index.ts @@ -15,7 +15,7 @@ declare global { getAttached(selector: string): Chainable; clearAllFilters(): Chainable; submitButton(buttonText?: string): Chainable; - searchAndSelectOption( + typeAndSelectOption( element: string, referance: string, ): Chainable; diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json index 9c019786170..114000b60f0 100644 --- a/cypress/tsconfig.json +++ b/cypress/tsconfig.json @@ -1,11 +1,10 @@ { "compilerOptions": { - "baseUrl": "../node_modules", + "baseUrl": "./", "target": "es5", "lib": ["es5", "dom", "es2015", "es2016", "es2017", "es2018", "es2019", "es2020"], - "types": ["cypress"], "typeRoots": ["./support"], "resolveJsonModule": true }, - "include": ["**/*.ts", "support/commands.js"], -} + "include": ["**/*.cy.ts", "support/commands.ts","**/*.ts"], +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 59a22853fd5..e66a3ea4ead 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@googlemaps/react-wrapper": "^1.1.35", "@googlemaps/typescript-guards": "^2.0.3", "@headlessui/react": "^2.1.2", + "@hello-pangea/dnd": "^17.0.0", "@pnotify/core": "^5.2.0", "@pnotify/mobile": "^5.2.0", "@radix-ui/react-icons": "^1.3.0", @@ -28,6 +29,7 @@ "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "cross-env": "^7.0.3", + "cypress": "^13.14.2", "dayjs": "^1.11.11", "echarts": "^5.5.1", "echarts-for-react": "^3.0.2", @@ -36,15 +38,11 @@ "i18next": "^23.11.4", "i18next-browser-languagedetector": "^7.2.1", "lodash-es": "^4.17.21", - "lucide-react": "^0.446.0", "postcss-loader": "^7.3.3", "qrcode.react": "^3.1.0", "raviger": "^4.1.2", "react": "18.3.1", "react-copy-to-clipboard": "^5.1.0", - "react-dnd": "^16.0.1", - "react-dnd-html5-backend": "^16.0.1", - "react-dnd-scrolling": "^1.3.8", "react-dom": "18.3.1", "react-google-recaptcha": "^3.1.0", "react-i18next": "^15.0.2", @@ -65,7 +63,6 @@ "@tailwindcss/container-queries": "^0.1.1", "@tailwindcss/forms": "^0.5.7", "@tailwindcss/typography": "^0.5.13", - "@types/cypress": "^1.1.3", "@types/events": "^3.0.3", "@types/google.maps": "^3.55.8", "@types/lodash-es": "^4.17.12", @@ -76,10 +73,10 @@ "@types/react-csv": "^1.1.10", "@types/react-dom": "^18.3.0", "@types/react-google-recaptcha": "^2.1.9", + "@types/uuid": "^10.0.0", "@typescript-eslint/eslint-plugin": "^7.18.0", "@vitejs/plugin-react-swc": "^3.6.0", "autoprefixer": "^10.4.19", - "cypress": "^13.14.2", "cypress-localstorage-commands": "^2.2.5", "cypress-split": "^1.23.2", "eslint-config-prettier": "^9.1.0", @@ -88,7 +85,6 @@ "eslint-plugin-prettier": "^5.2.1", "eslint-plugin-react": "^7.35.0", "eslint-plugin-react-hooks": "^4.6.2", - "gentype": "^4.5.0", "glob": "^11.0.0", "husky": "^8.0.3", "lint-staged": "^13.2.3", @@ -96,7 +92,6 @@ "postcss": "^8.4.38", "prettier": "^3.3.3", "prettier-plugin-tailwindcss": "^0.6.5", - "prop-types": "^15.8.1", "redux-devtools-extension": "^2.13.9", "snyk": "^1.1291.0", "tailwindcss": "^3.4.3", @@ -1980,7 +1975,6 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "dev": true, "optional": true, "engines": { "node": ">=0.1.90" @@ -1990,7 +1984,6 @@ "version": "3.0.5", "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.5.tgz", "integrity": "sha512-v+XHd9XmWbufxF1/bTaVm2yhbxY+TB4YtWRqF2zaXBlDNMkls34KiATz0AVDLavL3iB6bQk9/7n3oY1EoLSWGA==", - "dev": true, "dependencies": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -2019,7 +2012,6 @@ "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, "bin": { "uuid": "dist/bin/uuid" } @@ -2028,7 +2020,6 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", - "dev": true, "dependencies": { "debug": "^3.1.0", "lodash.once": "^4.1.1" @@ -2038,7 +2029,6 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, "dependencies": { "ms": "^2.1.1" } @@ -2623,6 +2613,51 @@ "react-dom": "^18" } }, + "node_modules/@hello-pangea/dnd": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@hello-pangea/dnd/-/dnd-17.0.0.tgz", + "integrity": "sha512-LDDPOix/5N0j5QZxubiW9T0M0+1PR0rTDWeZF5pu1Tz91UQnuVK4qQ/EjY83Qm2QeX0eM8qDXANfDh3VVqtR4Q==", + "dependencies": { + "@babel/runtime": "^7.25.6", + "css-box-model": "^1.2.1", + "memoize-one": "^6.0.0", + "raf-schd": "^4.0.3", + "react-redux": "^9.1.2", + "redux": "^5.0.1", + "use-memo-one": "^1.1.3" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@hello-pangea/dnd/node_modules/react-redux": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.1.2.tgz", + "integrity": "sha512-0OA4dhM1W48l3uzmv6B7TXPCGmokUU4p1M44DGN2/D9a1FjVPukVjER1PcPX97jIg6aUeLq1XJo1IpfbgULn0w==", + "dependencies": { + "@types/use-sync-external-store": "^0.0.3", + "use-sync-external-store": "^1.0.0" + }, + "peerDependencies": { + "@types/react": "^18.2.25", + "react": "^18.0", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/@hello-pangea/dnd/node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==" + }, "node_modules/@humanwhocodes/config-array": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", @@ -3578,21 +3613,6 @@ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, - "node_modules/@react-dnd/asap": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-5.0.2.tgz", - "integrity": "sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A==" - }, - "node_modules/@react-dnd/invariant": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-4.0.2.tgz", - "integrity": "sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw==" - }, - "node_modules/@react-dnd/shallowequal": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz", - "integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==" - }, "node_modules/@react-stately/utils": { "version": "3.10.4", "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.4.tgz", @@ -4475,16 +4495,6 @@ "@types/node": "*" } }, - "node_modules/@types/cypress": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@types/cypress/-/cypress-1.1.3.tgz", - "integrity": "sha512-OXe0Gw8LeCflkG1oPgFpyrYWJmEKqYncBsD/J0r17r0ETx/TnIGDNLwXt/pFYSYuYTpzcq1q3g62M9DrfsBL4g==", - "deprecated": "This is a stub types definition for cypress (https://cypress.io). cypress provides its own type definitions, so you don't need @types/cypress installed!", - "dev": true, - "dependencies": { - "cypress": "*" - } - }, "node_modules/@types/debug": { "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", @@ -4677,14 +4687,12 @@ "node_modules/@types/sinonjs__fake-timers": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", - "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", - "dev": true + "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==" }, "node_modules/@types/sizzle": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.8.tgz", - "integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==", - "dev": true + "integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==" }, "node_modules/@types/supports-color": { "version": "8.1.3", @@ -4709,11 +4717,16 @@ "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" }, + "node_modules/@types/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", + "dev": true + }, "node_modules/@types/yauzl": { "version": "2.10.3", "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", - "dev": true, "optional": true, "dependencies": { "@types/node": "*" @@ -5222,7 +5235,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -5260,7 +5272,6 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, "engines": { "node": ">=6" } @@ -5269,7 +5280,6 @@ "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, "dependencies": { "type-fest": "^0.21.3" }, @@ -5284,7 +5294,6 @@ "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, "engines": { "node": ">=10" }, @@ -5347,7 +5356,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", - "dev": true, "funding": [ { "type": "github", @@ -5538,7 +5546,6 @@ "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, "dependencies": { "safer-buffer": "~2.1.0" } @@ -5547,7 +5554,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, "engines": { "node": ">=0.8" } @@ -5565,7 +5571,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, "engines": { "node": ">=8" } @@ -5573,8 +5578,7 @@ "node_modules/async": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "dev": true + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==" }, "node_modules/asynckit": { "version": "0.4.0", @@ -5585,7 +5589,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, "engines": { "node": ">= 4.0.0" } @@ -5646,7 +5649,6 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true, "engines": { "node": "*" } @@ -5654,8 +5656,7 @@ "node_modules/aws4": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", - "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", - "dev": true + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==" }, "node_modules/axios": { "version": "1.7.7", @@ -5742,7 +5743,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, "funding": [ { "type": "github", @@ -5762,7 +5762,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dev": true, "dependencies": { "tweetnacl": "^0.14.3" } @@ -5781,14 +5780,12 @@ "node_modules/blob-util": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", - "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", - "dev": true + "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==" }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, "node_modules/boolean": { "version": "3.2.0", @@ -5889,7 +5886,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, "funding": [ { "type": "github", @@ -5913,7 +5909,6 @@ "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, "engines": { "node": "*" } @@ -5927,7 +5922,6 @@ "version": "2.4.0", "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", - "dev": true, "engines": { "node": ">=6" } @@ -5936,7 +5930,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dev": true, "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -6004,8 +5997,7 @@ "node_modules/caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" }, "node_modules/ccount": { "version": "2.0.1", @@ -6033,7 +6025,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -6049,7 +6040,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -6101,7 +6091,6 @@ "version": "2.24.0", "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==", - "dev": true, "engines": { "node": ">= 0.8.0" } @@ -6162,7 +6151,6 @@ "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, "funding": [ { "type": "github", @@ -6196,7 +6184,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, "engines": { "node": ">=6" } @@ -6205,7 +6192,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, "dependencies": { "restore-cursor": "^3.1.0" }, @@ -6217,7 +6203,6 @@ "version": "0.6.5", "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", - "dev": true, "dependencies": { "string-width": "^4.2.0" }, @@ -6232,7 +6217,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", - "dev": true, "dependencies": { "slice-ansi": "^3.0.0", "string-width": "^4.2.0" @@ -6297,8 +6281,7 @@ "node_modules/colorette": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" }, "node_modules/combined-stream": { "version": "1.0.8", @@ -6324,7 +6307,6 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", - "dev": true, "engines": { "node": ">= 6" } @@ -6333,7 +6315,6 @@ "version": "1.8.2", "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", - "dev": true, "engines": { "node": ">=4.0.0" } @@ -6416,8 +6397,7 @@ "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" }, "node_modules/cosmiconfig": { "version": "8.3.6", @@ -6494,6 +6474,14 @@ "node": ">=8" } }, + "node_modules/css-box-model": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz", + "integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==", + "dependencies": { + "tiny-invariant": "^1.0.6" + } + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -6511,13 +6499,12 @@ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/cypress": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.15.0.tgz", - "integrity": "sha512-53aO7PwOfi604qzOkCSzNlWquCynLlKE/rmmpSPcziRH6LNfaDUAklQT6WJIsD8ywxlIy+uVZsnTMCCQVd2kTw==", - "dev": true, + "version": "13.14.2", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.14.2.tgz", + "integrity": "sha512-lsiQrN17vHMB2fnvxIrKLAjOr9bPwsNbPZNrWf99s4u+DVmCY6U+w7O3GGG9FvP4EUVYaDu+guWeNLiUzBrqvA==", "hasInstallScript": true, "dependencies": { - "@cypress/request": "^3.0.4", + "@cypress/request": "^3.0.1", "@cypress/xvfb": "^1.2.4", "@types/sinonjs__fake-timers": "8.1.1", "@types/sizzle": "^2.3.2", @@ -6602,14 +6589,12 @@ "node_modules/cypress/node_modules/proxy-from-env": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", - "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==", - "dev": true + "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==" }, "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, "dependencies": { "assert-plus": "^1.0.0" }, @@ -6786,7 +6771,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -7054,16 +7038,6 @@ "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" }, - "node_modules/dnd-core": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-16.0.1.tgz", - "integrity": "sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==", - "dependencies": { - "@react-dnd/asap": "^5.0.1", - "@react-dnd/invariant": "^4.0.1", - "redux": "^4.2.0" - } - }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -7097,7 +7071,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, "dependencies": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -7159,7 +7132,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "dependencies": { "once": "^1.4.0" } @@ -7180,7 +7152,6 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", - "dev": true, "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" @@ -7279,7 +7250,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, "dependencies": { "get-intrinsic": "^1.2.4" }, @@ -7291,7 +7261,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, "engines": { "node": ">= 0.4" } @@ -7915,8 +7884,7 @@ "node_modules/eventemitter2": { "version": "6.4.7", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz", - "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==", - "dev": true + "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==" }, "node_modules/eventemitter3": { "version": "5.0.1", @@ -7936,7 +7904,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "dev": true, "dependencies": { "cross-spawn": "^7.0.0", "get-stream": "^5.0.0", @@ -7959,7 +7926,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", - "dev": true, "dependencies": { "pify": "^2.2.0" }, @@ -7976,7 +7942,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", @@ -7996,7 +7961,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true, "engines": [ "node >=0.6.0" ] @@ -8077,7 +8041,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, "dependencies": { "pend": "~1.2.0" } @@ -8086,7 +8049,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, "dependencies": { "escape-string-regexp": "^1.0.5" }, @@ -8101,7 +8063,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, "engines": { "node": ">=0.8.0" } @@ -8366,7 +8327,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true, "engines": { "node": "*" } @@ -8409,7 +8369,6 @@ "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", @@ -8534,16 +8493,6 @@ "node": ">=6.9.0" } }, - "node_modules/gentype": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/gentype/-/gentype-4.5.0.tgz", - "integrity": "sha512-XqHBQPS6Qb2HSgNJAwYRXbQJ4LSvz+MgNvuWnj8bz0teSorsy2kDxA6F1eZx5ft8cnfKAls4uNEgd5uNcPbQDg==", - "dev": true, - "hasInstallScript": true, - "bin": { - "gentype": "gentype.exe" - } - }, "node_modules/get-amd-module-type": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/get-amd-module-type/-/get-amd-module-type-6.0.0.tgz", @@ -8561,7 +8510,6 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", @@ -8586,7 +8534,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, "dependencies": { "pump": "^3.0.0" }, @@ -8630,7 +8577,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", - "dev": true, "dependencies": { "async": "^3.2.0" } @@ -8639,7 +8585,6 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, "dependencies": { "assert-plus": "^1.0.0" } @@ -8720,7 +8665,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", - "dev": true, "dependencies": { "ini": "2.0.0" }, @@ -8802,7 +8746,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -8842,7 +8785,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, "dependencies": { "es-define-property": "^1.0.0" }, @@ -8854,7 +8796,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -8866,7 +8807,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -9186,7 +9126,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.4.0.tgz", "integrity": "sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==", - "dev": true, "dependencies": { "assert-plus": "^1.0.0", "jsprim": "^2.0.2", @@ -9213,7 +9152,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "dev": true, "engines": { "node": ">=8.12.0" } @@ -9279,7 +9217,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, "funding": [ { "type": "github", @@ -9349,7 +9286,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, "engines": { "node": ">=8" } @@ -9375,7 +9311,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "dev": true, "engines": { "node": ">=10" } @@ -9561,7 +9496,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", - "dev": true, "dependencies": { "ci-info": "^3.2.0" }, @@ -9697,7 +9631,6 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "dev": true, "dependencies": { "global-dirs": "^3.0.0", "is-path-inside": "^3.0.2" @@ -9775,7 +9708,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, "engines": { "node": ">=8" } @@ -9847,7 +9779,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, "engines": { "node": ">=8" }, @@ -9903,14 +9834,12 @@ "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, "engines": { "node": ">=10" }, @@ -9990,8 +9919,7 @@ "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" }, "node_modules/iterator.prototype": { "version": "1.1.2", @@ -10102,8 +10030,7 @@ "node_modules/jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" }, "node_modules/jsesc": { "version": "3.0.2", @@ -10132,8 +10059,7 @@ "node_modules/json-schema": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" }, "node_modules/json-schema-traverse": { "version": "0.4.1", @@ -10151,8 +10077,7 @@ "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" }, "node_modules/json5": { "version": "2.2.3", @@ -10170,7 +10095,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, "dependencies": { "universalify": "^2.0.0" }, @@ -10191,7 +10115,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", - "dev": true, "engines": [ "node >=0.6.0" ], @@ -10239,7 +10162,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==", - "dev": true, "engines": { "node": "> 0.8" } @@ -10731,7 +10653,6 @@ "version": "3.14.0", "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", - "dev": true, "dependencies": { "cli-truncate": "^2.1.0", "colorette": "^2.0.16", @@ -10758,7 +10679,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -10855,8 +10775,7 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "node_modules/lodash-es": { "version": "4.17.21", @@ -10890,8 +10809,7 @@ "node_modules/lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", - "dev": true + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" }, "node_modules/lodash.sortby": { "version": "4.7.0", @@ -10899,16 +10817,10 @@ "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", "dev": true }, - "node_modules/lodash.throttle": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", - "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==" - }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -10924,7 +10836,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", - "dev": true, "dependencies": { "ansi-escapes": "^4.3.0", "cli-cursor": "^3.1.0", @@ -10942,7 +10853,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -10959,7 +10869,6 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -11005,14 +10914,6 @@ "yallist": "^3.0.2" } }, - "node_modules/lucide-react": { - "version": "0.446.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.446.0.tgz", - "integrity": "sha512-BU7gy8MfBMqvEdDPH79VhOXSEgyG8TSPOKWaExWGCQVqnGH7wGgDngPbofu+KdtVjPQBWbEmnfMTq90CTiiDRg==", - "peerDependencies": { - "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc" - } - }, "node_modules/magic-string": { "version": "0.30.11", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", @@ -12015,6 +11916,11 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" + }, "node_modules/merge-refs": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/merge-refs/-/merge-refs-1.3.0.tgz", @@ -12709,7 +12615,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, "engines": { "node": ">=6" } @@ -12753,7 +12658,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -13091,7 +12995,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, "dependencies": { "path-key": "^3.0.0" }, @@ -13132,7 +13035,6 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -13236,7 +13138,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "devOptional": true, "dependencies": { "wrappy": "1" } @@ -13245,7 +13146,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, "dependencies": { "mimic-fn": "^2.1.0" }, @@ -13277,8 +13177,7 @@ "node_modules/ospath": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", - "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==", - "dev": true + "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==" }, "node_modules/p-limit": { "version": "3.1.0", @@ -13316,7 +13215,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, "dependencies": { "aggregate-error": "^3.0.0" }, @@ -13482,8 +13380,7 @@ "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" }, "node_modules/performance-now": { "version": "2.1.0", @@ -13934,7 +13831,6 @@ "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "dev": true, "engines": { "node": ">=6" }, @@ -13955,7 +13851,6 @@ "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true, "engines": { "node": ">= 0.6.0" } @@ -14006,14 +13901,12 @@ "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" }, "node_modules/pump": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", - "dev": true, "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -14039,7 +13932,6 @@ "version": "6.13.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "dev": true, "dependencies": { "side-channel": "^1.0.6" }, @@ -14053,8 +13945,7 @@ "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" }, "node_modules/queue-microtask": { "version": "1.2.3", @@ -14081,13 +13972,10 @@ "integrity": "sha512-twwRO/ilhlG/FIgYeKGFqyHhoEhqgnKVkcmqMKi2r524gz3ZbDTcyFt38E9xjJI2vT+KbRNHVbnJ/e0I25Azwg==", "dev": true }, - "node_modules/raf": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", - "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", - "dependencies": { - "performance-now": "^2.1.0" - } + "node_modules/raf-schd": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.3.tgz", + "integrity": "sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==" }, "node_modules/ramda": { "version": "0.29.0", @@ -14153,59 +14041,6 @@ "react": "^15.3.0 || 16 || 17 || 18" } }, - "node_modules/react-dnd": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-16.0.1.tgz", - "integrity": "sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==", - "dependencies": { - "@react-dnd/invariant": "^4.0.1", - "@react-dnd/shallowequal": "^4.0.1", - "dnd-core": "^16.0.1", - "fast-deep-equal": "^3.1.3", - "hoist-non-react-statics": "^3.3.2" - }, - "peerDependencies": { - "@types/hoist-non-react-statics": ">= 3.3.1", - "@types/node": ">= 12", - "@types/react": ">= 16", - "react": ">= 16.14" - }, - "peerDependenciesMeta": { - "@types/hoist-non-react-statics": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@types/react": { - "optional": true - } - } - }, - "node_modules/react-dnd-html5-backend": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz", - "integrity": "sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==", - "dependencies": { - "dnd-core": "^16.0.1" - } - }, - "node_modules/react-dnd-scrolling": { - "version": "1.3.10", - "resolved": "https://registry.npmjs.org/react-dnd-scrolling/-/react-dnd-scrolling-1.3.10.tgz", - "integrity": "sha512-Vbe7tp6ZC2kgBx/8P1LXa3+3ao61Ve8HcoVzicnAuRiaV/r3lmccE9JVsa0TeZ+pzTBodb+MzQW0tMOMSRmtwg==", - "dependencies": { - "hoist-non-react-statics": "3.x", - "lodash.throttle": "^4.1.1", - "prop-types": "15.x", - "raf": "^3.4.1" - }, - "peerDependencies": { - "react": "16.x || 17.x || 18.x", - "react-dnd": "10.x || 11.x || 14.x || 15.x || 16.x", - "react-dom": "16.x || 17.x || 18.x" - } - }, "node_modules/react-dom": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", @@ -15495,7 +15330,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==", - "dev": true, "dependencies": { "throttleit": "^1.0.0" } @@ -15582,8 +15416,7 @@ "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, "node_modules/resolve": { "version": "2.0.0-next.5", @@ -15632,7 +15465,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" @@ -15662,8 +15494,7 @@ "node_modules/rfdc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "dev": true + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==" }, "node_modules/rimraf": { "version": "3.0.2", @@ -15802,7 +15633,6 @@ "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dev": true, "dependencies": { "tslib": "^2.1.0" } @@ -15875,8 +15705,7 @@ "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/sass-lookup": { "version": "6.0.1", @@ -15995,7 +15824,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -16106,7 +15934,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -16123,8 +15950,7 @@ "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "devOptional": true + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "node_modules/simple-bin-help": { "version": "1.8.0", @@ -16184,7 +16010,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -16337,7 +16162,6 @@ "version": "1.18.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", - "dev": true, "dependencies": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -16583,7 +16407,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, "engines": { "node": ">=6" } @@ -17015,7 +16838,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz", "integrity": "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==", - "dev": true, "funding": { "url": "https://github.com/sponsors/sindresorhus" } @@ -17023,8 +16845,7 @@ "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" }, "node_modules/tiny-invariant": { "version": "1.3.3", @@ -17074,7 +16895,6 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", - "dev": true, "engines": { "node": ">=14.14" } @@ -17108,7 +16928,6 @@ "version": "4.1.4", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", - "dev": true, "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", @@ -17123,7 +16942,6 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true, "engines": { "node": ">= 4.0.0" } @@ -17220,7 +17038,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, "dependencies": { "safe-buffer": "^5.0.1" }, @@ -17231,8 +17048,7 @@ "node_modules/tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" }, "node_modules/type-check": { "version": "0.4.0", @@ -17732,7 +17548,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, "engines": { "node": ">= 10.0.0" } @@ -17741,7 +17556,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "dev": true, "engines": { "node": ">=8" } @@ -17798,7 +17612,6 @@ "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -17813,6 +17626,14 @@ "react-dom": ">=16.8" } }, + "node_modules/use-memo-one": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.3.tgz", + "integrity": "sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/use-sync-external-store": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", @@ -17884,7 +17705,6 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, "engines": [ "node >=0.6.0" ], @@ -19605,8 +19425,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "devOptional": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/xlsx": { "version": "0.18.5", @@ -19647,7 +19466,6 @@ "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" diff --git a/package.json b/package.json index 68de432e82e..850bba2edae 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "@googlemaps/react-wrapper": "^1.1.35", "@googlemaps/typescript-guards": "^2.0.3", "@headlessui/react": "^2.1.2", + "@hello-pangea/dnd": "^17.0.0", "@pnotify/core": "^5.2.0", "@pnotify/mobile": "^5.2.0", "@radix-ui/react-icons": "^1.3.0", @@ -63,6 +64,7 @@ "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "cross-env": "^7.0.3", + "cypress": "^13.14.2", "dayjs": "^1.11.11", "echarts": "^5.5.1", "echarts-for-react": "^3.0.2", @@ -71,15 +73,11 @@ "i18next": "^23.11.4", "i18next-browser-languagedetector": "^7.2.1", "lodash-es": "^4.17.21", - "lucide-react": "^0.446.0", "postcss-loader": "^7.3.3", "qrcode.react": "^3.1.0", "raviger": "^4.1.2", "react": "18.3.1", "react-copy-to-clipboard": "^5.1.0", - "react-dnd": "^16.0.1", - "react-dnd-html5-backend": "^16.0.1", - "react-dnd-scrolling": "^1.3.8", "react-dom": "18.3.1", "react-google-recaptcha": "^3.1.0", "react-i18next": "^15.0.2", @@ -100,7 +98,6 @@ "@tailwindcss/container-queries": "^0.1.1", "@tailwindcss/forms": "^0.5.7", "@tailwindcss/typography": "^0.5.13", - "@types/cypress": "^1.1.3", "@types/events": "^3.0.3", "@types/google.maps": "^3.55.8", "@types/lodash-es": "^4.17.12", @@ -111,10 +108,10 @@ "@types/react-csv": "^1.1.10", "@types/react-dom": "^18.3.0", "@types/react-google-recaptcha": "^2.1.9", + "@types/uuid": "^10.0.0", "@typescript-eslint/eslint-plugin": "^7.18.0", "@vitejs/plugin-react-swc": "^3.6.0", "autoprefixer": "^10.4.19", - "cypress": "^13.14.2", "cypress-localstorage-commands": "^2.2.5", "cypress-split": "^1.23.2", "eslint-config-prettier": "^9.1.0", @@ -123,7 +120,6 @@ "eslint-plugin-prettier": "^5.2.1", "eslint-plugin-react": "^7.35.0", "eslint-plugin-react-hooks": "^4.6.2", - "gentype": "^4.5.0", "glob": "^11.0.0", "husky": "^8.0.3", "lint-staged": "^13.2.3", @@ -131,7 +127,6 @@ "postcss": "^8.4.38", "prettier": "^3.3.3", "prettier-plugin-tailwindcss": "^0.6.5", - "prop-types": "^15.8.1", "redux-devtools-extension": "^2.13.9", "snyk": "^1.1291.0", "tailwindcss": "^3.4.3", diff --git a/src/Components/ErrorPages/SessionExpired.tsx b/src/Components/ErrorPages/SessionExpired.tsx index 419c9c44dce..32036a0319d 100644 --- a/src/Components/ErrorPages/SessionExpired.tsx +++ b/src/Components/ErrorPages/SessionExpired.tsx @@ -1,23 +1,16 @@ import * as Notification from "../../Utils/Notifications"; -import { useNavigate } from "raviger"; import { useEffect } from "react"; import { useTranslation } from "react-i18next"; import { useAuthContext } from "../../Common/hooks/useAuthUser"; export default function SessionExpired() { - const { signOut, user } = useAuthContext(); - const isAuthenticated = !!user; - const navigate = useNavigate(); + const { signOut } = useAuthContext(); const { t } = useTranslation(); useEffect(() => { Notification.closeAllNotifications(); }, []); - if (isAuthenticated) { - navigate("/"); - } - return (
diff --git a/src/Components/Facility/ConsultationDetails/index.tsx b/src/Components/Facility/ConsultationDetails/index.tsx index 53e137d12eb..6970898a158 100644 --- a/src/Components/Facility/ConsultationDetails/index.tsx +++ b/src/Components/Facility/ConsultationDetails/index.tsx @@ -256,6 +256,7 @@ export const ConsultationDetails = (props: any) => { {!consultationData.discharge_date && ( <>
diff --git a/src/Components/Facility/models.tsx b/src/Components/Facility/models.tsx index bbda967a49a..5baa63c289c 100644 --- a/src/Components/Facility/models.tsx +++ b/src/Components/Facility/models.tsx @@ -5,6 +5,7 @@ import { ConsultationSuggestionValue, DISCHARGE_REASONS, PATIENT_NOTES_THREADS, + SHIFTING_CHOICES_PEACETIME, UserRole, } from "../../Common/constants"; import { FeatureFlag } from "../../Utils/featureFlags"; @@ -15,12 +16,13 @@ import { DailyRoundsModel, FacilityNameModel, FileUploadModel, + PatientModel, } from "../Patient/models"; import { EncounterSymptom } from "../Symptoms/types"; +import { UserBareMinimum, UserModel } from "../Users/models"; import { InvestigationType } from "../Common/prescription-builder/InvestigationBuilder"; import { ProcedureType } from "../Common/prescription-builder/ProcedureBuilder"; import { RouteToFacility } from "../Common/RouteToFacilitySelect"; -import { UserBareMinimum } from "../Users/models"; export interface LocalBodyModel { id: number; @@ -677,3 +679,50 @@ export type PatientTransferResponse = { date_of_birth: string; facility_object: BaseFacilityModel; }; + +export interface ShiftingModel { + assigned_facility: string; + assigned_facility_external: string | null; + assigned_facility_object: FacilityModel; + created_date: string; + emergency: boolean; + external_id: string; + id: string; + modified_date: string; + origin_facility_object: FacilityModel; + patient: string; + patient_object: PatientModel; + shifting_approving_facility_object: FacilityModel | null; + status: (typeof SHIFTING_CHOICES_PEACETIME)[number]["text"]; + assigned_to_object?: UserModel; +} + +export interface ResourceModel { + approving_facility: string | null; + approving_facility_object: FacilityModel | null; + assigned_facility: string | null; + assigned_facility_object: FacilityModel | null; + assigned_quantity: number; + assigned_to: string | null; + assigned_to_object: UserModel | null; + category: string; + created_by: number; + created_by_object: UserModel; + created_date: string; + emergency: boolean; + id: string; + is_assigned_to_user: boolean; + last_edited_by: number; + last_edited_by_object: UserModel; + modified_date: string; + origin_facility: string; + origin_facility_object: FacilityModel; + priority: number | null; + reason: string; + refering_facility_contact_name: string; + refering_facility_contact_number: string; + requested_quantity: number; + status: string; + sub_category: string; + title: string; +} diff --git a/src/Components/Form/Form.tsx b/src/Components/Form/Form.tsx index 31afc594447..4bf4bd22d01 100644 --- a/src/Components/Form/Form.tsx +++ b/src/Components/Form/Form.tsx @@ -13,7 +13,6 @@ type Props = { className?: string; defaults: T; asyncGetDefaults?: (() => Promise) | false; - onlyChild?: boolean; validate?: (form: T) => FormErrors; onSubmit: (form: T) => Promise | void>; onCancel?: () => void; @@ -23,6 +22,7 @@ type Props = { cancelLabel?: string; onDraftRestore?: (newState: FormState) => void; children: (props: FormContextValue) => React.ReactNode; + hideRestoreDraft?: boolean; }; const Form = ({ @@ -87,47 +87,43 @@ const Form = ({ props.onDraftRestore?.(newState); }} formData={state.form} - /> - ) => { - return { - name, - id: name, - onChange: ({ name, value }: FieldChangeEvent) => - dispatch({ - type: "set_field", - name, - value, - error: validate?.(value), - }), - value: state.form[name], - error: state.errors[name], - disabled, - }; - }} + hidden={props.hideRestoreDraft} > - {props.onlyChild ? ( - {props.children} - ) : ( - <> -
- {props.children} -
-
- - -
- - )} -
+ ) => { + return { + name, + id: name, + onChange: ({ name, value }: FieldChangeEvent) => + dispatch({ + type: "set_field", + name, + value, + error: validate?.(value), + }), + value: state.form[name], + error: state.errors[name], + disabled, + }; + }} + > +
+ {props.children} +
+
+ + +
+
+ ); }; diff --git a/src/Components/Kanban/Board.tsx b/src/Components/Kanban/Board.tsx new file mode 100644 index 00000000000..d2ab5da998f --- /dev/null +++ b/src/Components/Kanban/Board.tsx @@ -0,0 +1,190 @@ +import { + DragDropContext, + Draggable, + Droppable, + OnDragEndResponder, +} from "@hello-pangea/dnd"; +import { ReactNode, RefObject, useEffect, useRef, useState } from "react"; +import { QueryRoute } from "../../Utils/request/types"; +import { QueryOptions } from "../../Utils/request/useQuery"; +import CareIcon from "../../CAREUI/icons/CareIcon"; +import request from "../../Utils/request/request"; +import { useTranslation } from "react-i18next"; + +interface KanbanBoardProps { + title?: ReactNode; + onDragEnd: OnDragEndResponder; + sections: { + id: string; + title: ReactNode; + fetchOptions: ( + id: string, + ...args: unknown[] + ) => { + route: QueryRoute; + options?: QueryOptions; + }; + }[]; + itemRender: (item: T) => ReactNode; +} + +export default function KanbanBoard( + props: KanbanBoardProps, +) { + const board = useRef(null); + + return ( +
+
+
{props.title}
+
+ {[0, 1].map((button, i) => ( + + ))} +
+
+ +
+
+ {props.sections.map((section, i) => ( + + key={i} + section={section} + itemRender={props.itemRender} + boardRef={board} + /> + ))} +
+
+
+
+ ); +} + +export function KanbanSection( + props: Omit, "sections" | "onDragEnd"> & { + section: KanbanBoardProps["sections"][number]; + boardRef: RefObject; + }, +) { + const { section } = props; + const [offset, setOffset] = useState(0); + const [pages, setPages] = useState([]); + const [fetchingNextPage, setFetchingNextPage] = useState(false); + const [hasMore, setHasMore] = useState(true); + const [totalCount, setTotalCount] = useState(); + + const options = section.fetchOptions(section.id); + const sectionRef = useRef(null); + const defaultLimit = 14; + const { t } = useTranslation(); + + // should be replaced with useInfiniteQuery when we move over to react query + + const fetchNextPage = async (refresh: boolean = false) => { + if (!refresh && (fetchingNextPage || !hasMore)) return; + if (refresh) setPages([]); + const offsetToUse = refresh ? 0 : offset; + setFetchingNextPage(true); + const res = await request(options.route, { + ...options.options, + query: { ...options.options?.query, offsetToUse, limit: defaultLimit }, + }); + const newPages = refresh ? [] : [...pages]; + const page = Math.floor(offsetToUse / defaultLimit); + if (res.error) return; + newPages[page] = (res.data as any).results; + setPages(newPages); + setHasMore(!!(res.data as any)?.next); + setTotalCount((res.data as any)?.count); + setOffset(offsetToUse + defaultLimit); + setFetchingNextPage(false); + }; + + const items = pages.flat(); + + useEffect(() => { + const onBoardReachEnd = async () => { + const sectionElementHeight = + sectionRef.current?.getBoundingClientRect().height; + const scrolled = props.boardRef.current?.scrollTop; + // if user has scrolled 3/4th of the current items + if ( + scrolled && + sectionElementHeight && + scrolled > sectionElementHeight * (3 / 4) + ) { + fetchNextPage(); + } + }; + + props.boardRef.current?.addEventListener("scroll", onBoardReachEnd); + return () => + props.boardRef.current?.removeEventListener("scroll", onBoardReachEnd); + }, [props.boardRef, fetchingNextPage, hasMore]); + + useEffect(() => { + fetchNextPage(true); + }, [props.section]); + + return ( + + {(provided) => ( +
+
+
+
{section.title}
+
+ + {typeof totalCount === "undefined" ? "..." : totalCount} + +
+
+
+
+ {!fetchingNextPage && totalCount === 0 && ( +
+ {t("no_results_found")} +
+ )} + {items + .filter((item) => item) + .map((item, i) => ( + + {(provided) => ( +
+ {props.itemRender(item)} +
+ )} +
+ ))} + {fetchingNextPage && ( +
+ )} +
+
+ )} + + ); +} diff --git a/src/Components/LogUpdate/Sections/PressureSore/PressureSore.tsx b/src/Components/LogUpdate/Sections/PressureSore/PressureSore.tsx index a56457ef257..63970d4c25c 100644 --- a/src/Components/LogUpdate/Sections/PressureSore/PressureSore.tsx +++ b/src/Components/LogUpdate/Sections/PressureSore/PressureSore.tsx @@ -14,6 +14,7 @@ import { IPressureSore } from "../../../Patient/models"; import { Error } from "../../../../Utils/Notifications"; import { classNames, getValueDescription } from "../../../../Utils/utils"; import { calculatePushScore } from "./utils"; +import { useTranslation } from "react-i18next"; const PressureSore = ({ log, onChange, readonly }: LogUpdateSectionProps) => { const value = log.pressure_sore ?? []; @@ -104,6 +105,8 @@ const RegionEditor = (props: RegionEditorProps) => { const isReadOnly = !props.onSave; + const { t } = useTranslation(); + return ( {
{ onChange={(e) => update({ width: parseFloat(e.value) })} /> = { dosage_type: "REGULAR", + route: "ORAL", +}; +const DefaultPRNPrescription: Partial = { + dosage_type: "PRN", + route: "ORAL", }; -const DefaultPRNPrescription: Partial = { dosage_type: "PRN" }; diff --git a/src/Components/Patient/DiagnosesFilter.tsx b/src/Components/Patient/DiagnosesFilter.tsx index 1217e821389..ba58a549dac 100644 --- a/src/Components/Patient/DiagnosesFilter.tsx +++ b/src/Components/Patient/DiagnosesFilter.tsx @@ -68,6 +68,7 @@ export default function DiagnosesFilter(props: Props) { return ( {
-
+
Gender o.text} @@ -304,6 +305,7 @@ export default function PatientFilter(props: any) {
Category o.text} @@ -407,6 +409,7 @@ export default function PatientFilter(props: any) {
Telemedicine o.text} @@ -423,6 +426,7 @@ export default function PatientFilter(props: any) {
Respiratory Support o.text} @@ -455,6 +459,7 @@ export default function PatientFilter(props: any) { <> Review Missed (o === "true" ? "Yes" : "No")} @@ -469,6 +474,7 @@ export default function PatientFilter(props: any) {
Is Medico-Legal Case @@ -484,6 +490,7 @@ export default function PatientFilter(props: any) { />
{!props.dischargePage && ( -
+
Facility Facility type o.text} @@ -640,6 +648,7 @@ export default function PatientFilter(props: any) { LSG Body
-
+
District { } return ( -
- {statusDialog.show && ( - { - handleDialogClose("close"); - setResetNum(true); - }} - /> - )} - {statusDialog.transfer && ( - { - setResetNum(true); - handleDialogClose("close"); - }} - title="Patient Transfer Form" - className="max-w-md md:min-w-[600px]" - > - handleDialogClose("close")} - handleCancel={() => { - setResetNum(true); - handleDialogClose("close"); - }} - facilityId={facilityId} - /> - - )} - { - id - ? navigate(`/facility/${facilityId}/patient/${id}`) - : navigate(`/facility/${facilityId}`); - }} - componentRight={ - !state.form.abha_number && ( - - ) + + defaults={id ? state.form : initForm} + validate={validateForm} + onSubmit={handleSubmit} + submitLabel={buttonText} + onCancel={() => navigate("/facility")} + className="bg-transparent px-1 py-2 md:px-2" + onDraftRestore={(newState) => { + dispatch({ type: "set_state", state: newState }); + Promise.all([ + fetchDistricts(newState.form.state ?? 0), + fetchLocalBody(newState.form.district?.toString() ?? ""), + fetchWards(newState.form.local_body?.toString() ?? ""), + duplicateCheck(newState.form.phone_number ?? ""), + ]); + }} + noPadding + hideRestoreDraft + > + {(field) => { + if (!formField) setFormField(field); + if (resetNum) { + field("phone_number").onChange({ + name: "phone_number", + value: "+91", + }); + setResetNum(false); } - crumbsReplacements={{ - [facilityId]: { name: facilityObject?.name }, - [id ?? "????"]: { name: patientName }, - }} - /> -
-
-
- {" "} - Please enter the correct date of birth for the patient -
-

- Each patient in the system is uniquely identifiable by the number - and date of birth. Adding incorrect date of birth can result in - duplication of patient records. -

-
- <> - {showAlertMessage.show && ( - goBack()} - onClose={() => goBack()} - variant="primary" - action="Ok" - show - /> - )} - <> - - defaults={id ? state.form : initForm} - validate={validateForm} - onSubmit={handleSubmit} - submitLabel={buttonText} - onCancel={() => navigate("/facility")} - className="bg-transparent px-1 py-2 md:px-2" - onDraftRestore={(newState) => { - dispatch({ type: "set_state", state: newState }); - Promise.all([ - fetchDistricts(newState.form.state ?? 0), - fetchLocalBody(newState.form.district?.toString() ?? ""), - fetchWards(newState.form.local_body?.toString() ?? ""), - duplicateCheck(newState.form.phone_number ?? ""), - ]); + return ( +
+ {statusDialog.show && ( + { + handleDialogClose("close"); + setResetNum(true); + }} + /> + )} + {statusDialog.transfer && ( + { + setResetNum(true); + handleDialogClose("close"); + }} + title="Patient Transfer Form" + className="max-w-md md:min-w-[600px]" + > + handleDialogClose("close")} + handleCancel={() => { + setResetNum(true); + handleDialogClose("close"); + }} + facilityId={facilityId} + /> + + )} + { + id + ? navigate(`/facility/${facilityId}/patient/${id}`) + : navigate(`/facility/${facilityId}`); }} - noPadding - > - {(field) => { - if (!formField) setFormField(field); - if (resetNum) { - field("phone_number").onChange({ - name: "phone_number", - value: "+91", - }); - setResetNum(false); - } - return ( - <> - {careConfig.abdm.enabled && ( -
- {showLinkAbhaNumberModal && ( - setShowLinkAbhaNumberModal(false)} - onSuccess={(data: any) => { - if (id) { - navigate( - `/facility/${facilityId}/patient/${id}`, - ); - return; - } + componentRight={} + crumbsReplacements={{ + [facilityId]: { name: facilityObject?.name }, + [id ?? "????"]: { name: patientName }, + }} + /> +
+
+
+ {" "} + Please enter the correct date of birth for the patient +
+

+ Each patient in the system is uniquely identifiable by the + number and date of birth. Adding incorrect date of birth can + result in duplication of patient records. +

+
+ {!state.form.abha_number && ( +
+ +
+ )} + {showAlertMessage.show && ( + goBack()} + onClose={() => goBack()} + variant="primary" + action="Ok" + show + /> + )} + {careConfig.abdm.enabled && ( +
+ {showLinkAbhaNumberModal && ( + setShowLinkAbhaNumberModal(false)} + onSuccess={(data: any) => { + if (id) { + navigate(`/facility/${facilityId}/patient/${id}`); + return; + } - handleAbhaLinking(data, field); - }} - /> - )} - {state.form.abha_number && ( -
-
- null} - disabled={true} - error="" - /> -
-
- {state.form.health_id ? ( - null} - disabled={true} - error="" - /> - ) : ( -
- No Abha Address Associated with this ABHA - Number -
- )} -
-
- )} + handleAbhaLinking(data, field); + }} + /> + )} + {state.form.abha_number && ( +
+
+ null} + disabled={true} + error="" + />
- )} -
-

- Personal Details -

-
-
- { - if (!id) duplicateCheck(event.value); - field("phone_number").onChange(event); - if (isEmergencyNumberEnabled) { - field("emergency_phone_number").onChange({ - name: field("emergency_phone_number").name, - value: event.value, - }); - } - }} - types={["mobile", "landline"]} - /> - { - setIsEmergencyNumberEnabled(value); - value - ? field("emergency_phone_number").onChange({ - name: field("emergency_phone_number").name, - value: field("phone_number").value, - }) - : field("emergency_phone_number").onChange({ - name: field("emergency_phone_number").name, - value: initForm.emergency_phone_number, - }); - }} - /> -
-
- -
-
+
+ {state.form.health_id ? ( null} + disabled={true} + error="" /> -
-
- - {ageInputType === "age" ? "Age" : "Date of Birth"} - -
- + No Abha Address Associated with this ABHA Number +
+ )} +
+
+ )} +
+ )} +
+

+ Personal Details +

+
+
+ { + if (!id) duplicateCheck(event.value); + field("phone_number").onChange(event); + if (isEmergencyNumberEnabled) { + field("emergency_phone_number").onChange({ + name: field("emergency_phone_number").name, + value: event.value, + }); + } + }} + types={["mobile", "landline"]} + /> + { + setIsEmergencyNumberEnabled(value); + value + ? field("emergency_phone_number").onChange({ + name: field("emergency_phone_number").name, + value: field("phone_number").value, + }) + : field("emergency_phone_number").onChange({ + name: field("emergency_phone_number").name, + value: initForm.emergency_phone_number, + }); + }} + /> +
+
+ +
+
+ +
+
+ + {ageInputType === "age" ? "Age" : "Date of Birth"} + +
+ o.text} + optionValue={(o) => + o.value === "date_of_birth" ? "date_of_birth" : "age" + } + value={ageInputType} + onChange={(v) => { + if (v === "age" && ageInputType === "date_of_birth") { + setAgeInputType("alert_for_age"); + return; + } + setAgeInputType(v); + }} + /> +
+ {ageInputType !== "age" ? ( +
+ o.text} - optionValue={(o) => - o.value === "date_of_birth" - ? "date_of_birth" - : "age" - } - value={ageInputType} - onChange={(v) => { - if ( - v === "age" && - ageInputType === "date_of_birth" - ) { - setAgeInputType("alert_for_age"); - return; - } - setAgeInputType(v); - }} + position="LEFT" + disableFuture /> -
- {ageInputType !== "age" ? ( -
- -
- ) : ( -
- - {field("age").value !== "" && ( - <> - - Year of Birth: - - - YOB: - - - {new Date().getFullYear() - - field("age").value} - - - )} -

- } - placeholder="Enter the age" - type="number" - min={0} - /> -
- )} -
- -
- -
- While entering a patient's age is an option, - please note that only the year of birth will - be captured from this information. -
- - Recommended only when the patient's date of - birth is unknown - -
+ ) : ( +
+ + {field("age").value !== "" && ( + <> + + Year of Birth: + + + YOB: + + + {new Date().getFullYear() - + field("age").value} + + + )} +

} - action="Confirm" - variant="warning" - show={ageInputType == "alert_for_age"} - onClose={() => setAgeInputType("date_of_birth")} - onConfirm={() => setAgeInputType("age")} + placeholder="Enter the age" + type="number" + min={0} />
-
-
+ )} +
+
+ +
+ +
+ While entering a patient's age is an option, + please note that only the year of birth will be + captured from this information. +
+ + Recommended only when the patient's date of birth + is unknown + +
+ } + action="Confirm" + variant="warning" + show={ageInputType == "alert_for_age"} + onClose={() => setAgeInputType("date_of_birth")} + onConfirm={() => setAgeInputType("age")} + /> +
+
+
+ { + field("gender").onChange(e); + if (e.value !== "2") { + field("is_antenatal").onChange({ + name: "is_antenatal", + value: "false", + }); + + field("is_postpartum").onChange({ + name: "is_postpartum", + value: "false", + }); + } + }} + optionLabel={(o: any) => o.text} + optionValue={(o: any) => o.id} + /> +
+ + { +
+ option.label} + optionValue={(option) => option.value} + /> +
+ } +
+ + { +
+ +
+ } +
+ + option.label} + optionValue={(option) => option.value} + /> + + + + +
+ +
+
+ + +
+ +
+ { + field("pincode").onChange(e); + handlePincodeChange(e, field("pincode").onChange); + }} + /> + {showAutoFilledPincode && ( +
+ + + State and District auto-filled from Pincode + +
+ )} +
+
+ +
+
+ o} + optionValue={(o) => o} + /> +
+ {field("nationality").value === "India" ? ( + <> +
+ {isStateLoading ? ( + + ) : ( { - field("gender").onChange(e); - if (e.value !== "2") { - field("is_antenatal").onChange({ - name: "is_antenatal", - value: "false", - }); - - field("is_postpartum").onChange({ - name: "is_postpartum", - value: "false", - }); - } - }} - optionLabel={(o: any) => o.text} + placeholder="Choose State" + options={stateData ? stateData.results : []} + optionLabel={(o: any) => o.name} optionValue={(o: any) => o.id} + onChange={(e: any) => { + field("state").onChange(e); + field("district").onChange({ + name: "district", + value: undefined, + }); + field("local_body").onChange({ + name: "local_body", + value: undefined, + }); + field("ward").onChange({ + name: "ward", + value: undefined, + }); + fetchDistricts(e.value); + fetchLocalBody("0"); + fetchWards("0"); + }} /> -
- - { -
- option.label} - optionValue={(option) => option.value} - /> -
- } -
- - { -
- -
- } -
- - option.label} - optionValue={(option) => option.value} - /> - - - - -
- -
-
- + +
+ {isDistrictLoading ? ( +
+ +
+ ) : ( + o.name} + optionValue={(o: any) => o.id} + onChange={(e: any) => { + field("district").onChange(e); + field("local_body").onChange({ + name: "local_body", + value: undefined, + }); + field("ward").onChange({ + name: "ward", + value: undefined, + }); + fetchLocalBody(String(e.value)); + fetchWards("0"); + }} /> - -
+ )} +
-
- + {isLocalbodyLoading ? ( +
+ +
+ ) : ( + o.name} + optionValue={(o) => o.id} onChange={(e) => { - field("pincode").onChange(e); - handlePincodeChange(e, field("pincode").onChange); + field("local_body").onChange(e); + field("ward").onChange({ + name: "ward", + value: undefined, + }); + fetchWards(String(e.value)); }} /> - {showAutoFilledPincode && ( -
- - - State and District auto-filled from Pincode - -
- )} -
-
- -
-
+ )} +
+
+ {isWardLoading ? ( +
+ +
+ ) : ( o} - optionValue={(o) => o} + {...field("ward")} + label="Ward" + options={ward.sort(compareBy("number")).map((e) => { + return { + id: e.id, + name: e.number + ": " + e.name, + }; + })} + placeholder={ + field("local_body").value + ? "Choose Ward" + : "Select Localbody First" + } + disabled={!field("local_body").value} + optionLabel={(o: any) => o.name} + optionValue={(o: any) => o.id} + onChange={(e: any) => { + field("ward").onChange(e); + }} /> -
- {field("nationality").value === "India" ? ( - <> -
- {isStateLoading ? ( - - ) : ( - o.name} - optionValue={(o: any) => o.id} - onChange={(e: any) => { - field("state").onChange(e); - field("district").onChange({ - name: "district", - value: undefined, - }); - field("local_body").onChange({ - name: "local_body", - value: undefined, - }); - field("ward").onChange({ - name: "ward", - value: undefined, - }); - fetchDistricts(e.value); - fetchLocalBody("0"); - fetchWards("0"); - }} - /> - )} -
- -
- {isDistrictLoading ? ( -
- -
- ) : ( - o.name} - optionValue={(o: any) => o.id} - onChange={(e: any) => { - field("district").onChange(e); - field("local_body").onChange({ - name: "local_body", - value: undefined, - }); - field("ward").onChange({ - name: "ward", - value: undefined, - }); - fetchLocalBody(String(e.value)); - fetchWards("0"); - }} - /> - )} -
- -
- {isLocalbodyLoading ? ( -
- -
- ) : ( - o.name} - optionValue={(o) => o.id} - onChange={(e) => { - field("local_body").onChange(e); - field("ward").onChange({ - name: "ward", - value: undefined, - }); - fetchWards(String(e.value)); - }} - /> - )} -
-
- {isWardLoading ? ( -
- -
- ) : ( - { - return { - id: e.id, - name: e.number + ": " + e.name, - }; - })} - placeholder={ - field("local_body").value - ? "Choose Ward" - : "Select Localbody First" - } - disabled={!field("local_body").value} - optionLabel={(o: any) => o.name} - optionValue={(o: any) => o.id} - onChange={(e: any) => { - field("ward").onChange(e); - }} - /> - )} -
- - ) : ( -
- -
)}
+ + ) : ( +
+
- {field("nationality").value === "India" && ( -
- + )} +
+
+ {field("nationality").value === "India" && ( +
+ + } + title={ +

+ Social Profile +

+ } + expanded + > +
+
+ o.text} + optionValue={(o) => o.id} + /> + t(`ration_card__${o}`)} + optionValue={(o) => o} + /> + t(`SOCIOECONOMIC_STATUS__${o}`)} + optionValue={(o) => o} + value={field("meta_info").value?.socioeconomic_status} + onChange={({ name, value }) => + field("meta_info").onChange({ + name: "meta_info", + value: { + ...(field("meta_info").value ?? {}), + [name]: value, + }, + }) } - title={ -

- Social Profile -

+ /> + + t(`DOMESTIC_HEALTHCARE_SUPPORT__${o}`) } - expanded - > -
-
- o.text} - optionValue={(o) => o.id} - /> - t(`ration_card__${o}`)} - optionValue={(o) => o} - /> - - t(`SOCIOECONOMIC_STATUS__${o}`) - } - optionValue={(o) => o} - value={ - field("meta_info").value?.socioeconomic_status - } - onChange={({ name, value }) => - field("meta_info").onChange({ - name: "meta_info", - value: { - ...(field("meta_info").value ?? {}), - [name]: value, - }, - }) - } - /> - - t(`DOMESTIC_HEALTHCARE_SUPPORT__${o}`) - } - optionValue={(o) => o} - value={ - field("meta_info").value - ?.domestic_healthcare_support - } - onChange={({ name, value }) => - field("meta_info").onChange({ - name: "meta_info", - value: { - ...(field("meta_info").value ?? {}), - [name]: value, - }, - }) - } - /> -
-
- + optionValue={(o) => o} + value={ + field("meta_info").value + ?.domestic_healthcare_support + } + onChange={({ name, value }) => + field("meta_info").onChange({ + name: "meta_info", + value: { + ...(field("meta_info").value ?? {}), + [name]: value, + }, + }) + } + />
- )} -
- - } - title={ -

- COVID Details -

- } +
+ +
+ )} +
+ + } + title={ +

+ COVID Details +

+ } + > +
+
+
+ option.label} + optionValue={(option) => option.value} + /> +
+
+
+ -
-
-
- option.label} - optionValue={(option) => option.value} + { +
+
+
-
-
- - { -
-
- -
-
- option.label} - optionValue={(option) => option.value} - /> -
-
- o} - optionValue={(o) => o} - /> -
-
- -
-
- } -
-
-
-
+
option.label} optionValue={(option) => option.value} /> - -
- -
-
-
+
+ o} + optionValue={(o) => o} + /> +
+
-
- -
-
-

- Medical History -

-
-
- -
- -
- -
-
- - Any medical history? (Comorbidities) - -
- {MEDICAL_HISTORY_CHOICES.map((i) => { - return renderMedicalHistory( - i.id as number, - i.text, - field, - ); - })} -
- -
- -
- -
- -
- o} - optionValue={(o: any) => o} - /> -
-
+ } +
-
-
-

- Insurance Details -

- - setInsuranceDetails([ - ...insuranceDetails, - { - id: "", - subscriber_id: "", - policy_id: "", - insurer_id: "", - insurer_name: "", - }, - ]) +
+
+ option.label} + optionValue={(option) => option.value} + /> + - - Add Insurance Details - +
+ +
+
+
+
+
- setInsuranceDetails(value)} - error={insuranceDetailsError} - gridView - />
- - ); - }} - - - -
-
+
+ +
+
+

+ Medical History +

+
+
+ +
+ +
+ +
+
+ + Any medical history? (Comorbidities) + +
+ {MEDICAL_HISTORY_CHOICES.map((i) => { + return renderMedicalHistory( + i.id as number, + i.text, + field, + ); + })} +
+ +
+ +
+ +
+ +
+ o} + optionValue={(o: any) => o} + /> +
+
+
+
+
+

+ Insurance Details +

+ + setInsuranceDetails([ + ...insuranceDetails, + { + id: "", + subscriber_id: "", + policy_id: "", + insurer_id: "", + insurer_name: "", + }, + ]) + } + data-testid="add-insurance-button" + > + + Add Insurance Details + +
+ setInsuranceDetails(value)} + error={insuranceDetailsError} + gridView + /> +
+
+
+ ); + }} + ); }; diff --git a/src/Components/Patient/models.tsx b/src/Components/Patient/models.tsx index cf35680de11..d9e275fdc4a 100644 --- a/src/Components/Patient/models.tsx +++ b/src/Components/Patient/models.tsx @@ -135,6 +135,7 @@ export interface PatientModel { assigned_to?: { first_name?: string; username?: string; last_name?: string }; assigned_to_object?: AssignedToObjectModel; meta_info?: PatientMeta; + age?: string; } export interface SampleTestModel { diff --git a/src/Components/Resource/ResourceBoard.tsx b/src/Components/Resource/ResourceBoard.tsx deleted file mode 100644 index aa0b031ba0e..00000000000 --- a/src/Components/Resource/ResourceBoard.tsx +++ /dev/null @@ -1,301 +0,0 @@ -import { useState, useEffect } from "react"; -import { navigate } from "raviger"; -import { classNames, formatName } from "../../Utils/utils"; -import { useDrag, useDrop } from "react-dnd"; -import { formatDateTime } from "../../Utils/utils"; -import { ExportButton } from "../Common/Export"; -import dayjs from "../../Utils/dayjs"; -import useQuery from "../../Utils/request/useQuery"; -import routes from "../../Redux/api"; -import { PaginatedResponse } from "../../Utils/request/types"; -import { IResource } from "./models"; -import request from "../../Utils/request/request"; -import CareIcon from "../../CAREUI/icons/CareIcon"; - -interface boardProps { - board: string; - filterProp: any; - formatFilter: any; -} - -const renderBoardTitle = (board: string) => board; - -const reduceLoading = (action: string, current: any) => { - switch (action) { - case "MORE": - return { ...current, more: true }; - case "BOARD": - return { ...current, board: true }; - case "COMPLETE": - return { board: false, more: false }; - } -}; - -const ResourceCard = ({ resource }: any) => { - const [{ isDragging }, drag] = useDrag(() => ({ - type: "resource-card", - item: resource, - collect: (monitor) => ({ isDragging: !!monitor.isDragging() }), - })); - - return ( -
-
-
-
-
-
- {resource.title} -
-
- {resource.emergency && ( - - Emergency - - )} -
-
-
-
-
- -
- {(resource.origin_facility_object || {}).name} -
- -
-
-
- -
- {(resource.approving_facility_object || {}).name} -
- -
- {resource.assigned_facility_object && ( -
-
- - -
- {(resource.assigned_facility_object || {}).name || - "Yet to be decided"} -
- -
- )} -
-
- -
- {formatDateTime(resource.modified_date) || "--"} -
- -
- {resource.assigned_to_object && ( -
-
- -
- {formatName(resource.assigned_to_object)} -{" "} - {resource.assigned_to_object.user_type} -
- -
- )} -
-
-
- -
-
-
-
- ); -}; - -export default function ResourceBoard({ - board, - filterProp, - formatFilter, -}: boardProps) { - const [isLoading, setIsLoading] = useState({ board: "BOARD", more: false }); - const [{ isOver }, drop] = useDrop(() => ({ - accept: "resource-card", - drop: (item: any) => { - if (item.status !== board) { - navigate(`/resource/${item.id}/update?status=${board}`); - } - }, - collect: (monitor) => ({ isOver: !!monitor.isOver() }), - })); - const [offset, setOffSet] = useState(0); - const [data, setData] = useState>(); - - useEffect(() => { - setIsLoading((loading) => reduceLoading("BOARD", loading)); - }, [ - board, - filterProp.title, - filterProp.facility, - filterProp.origin_facility, - filterProp.approving_facility, - filterProp.assigned_facility, - filterProp.emergency, - filterProp.created_date_before, - filterProp.created_date_after, - filterProp.modified_date_before, - filterProp.modified_date_after, - filterProp.ordering, - ]); - - useQuery(routes.listResourceRequests, { - query: formatFilter({ - ...filterProp, - status: board, - }), - onResponse: ({ res, data: listResourceData }) => { - if (res?.ok && listResourceData) { - setData(listResourceData); - } - setIsLoading((loading) => reduceLoading("COMPLETE", loading)); - }, - }); - - const handlePagination = async () => { - setIsLoading((loading) => reduceLoading("MORE", loading)); - setOffSet(offset + 14); - const { res, data: newPageData } = await request( - routes.listResourceRequests, - { - query: formatFilter({ - ...filterProp, - status: board, - offset: offset, - }), - }, - ); - if (res?.ok && newPageData) { - setData((prev) => - prev - ? { ...prev, results: [...prev.results, ...newPageData.results] } - : newPageData, - ); - } - setIsLoading((loading) => reduceLoading("COMPLETE", loading)); - }; - - const boardFilter = (filter: string) => { - return data?.results - .filter(({ status }) => status === filter) - .map((resource: any) => ( - - )); - }; - - return ( -
-
-
-

- {renderBoardTitle(board)}{" "} - { - const { data } = await request( - routes.downloadResourceRequests, - { - query: { - ...formatFilter({ ...filterProp, status: board }), - csv: true, - }, - }, - ); - return data ?? null; - }} - filenamePrefix={`resource_requests_${board}`} - /> -

- - {data?.count || "0"} - -
-
-
- {isLoading.board ? ( -
-
-
-
-
-
-
-
-
-
-
-
-
- ) : data && data?.results.length > 0 ? ( - boardFilter(board) - ) : ( -

No requests to show.

- )} - {!isLoading.board && - data && - data?.results.length < (data?.count || 0) && - (isLoading.more ? ( -
- Loading -
- ) : ( - - ))} -
-
- ); -} diff --git a/src/Components/Resource/ResourceBoardView.tsx b/src/Components/Resource/ResourceBoardView.tsx index bd28cc5f5d2..ed6d63bbd77 100644 --- a/src/Components/Resource/ResourceBoardView.tsx +++ b/src/Components/Resource/ResourceBoardView.tsx @@ -1,9 +1,7 @@ import { useState } from "react"; -import { navigate } from "raviger"; +import { Link, navigate } from "raviger"; import ListFilter from "./ListFilter"; -import ResourceBoard from "./ResourceBoard"; import { RESOURCE_CHOICES } from "../../Common/constants"; -import withScrolling from "react-dnd-scrolling"; import BadgesList from "./BadgesList"; import { formatFilter } from "./Commons"; import useFilters from "../../Common/hooks/useFilters"; @@ -16,10 +14,12 @@ import SearchInput from "../Form/SearchInput"; import Tabs from "../Common/components/Tabs"; import request from "../../Utils/request/request"; import routes from "../../Redux/api"; +import KanbanBoard from "../Kanban/Board"; +import { ResourceModel } from "../Facility/models"; +import { classNames, formatDateTime, formatName } from "../../Utils/utils"; +import dayjs from "dayjs"; -import Loading from "@/Components/Common/Loading"; import PageTitle from "@/Components/Common/PageTitle"; -const ScrollingComponent = withScrolling("div"); const resourceStatusOptions = RESOURCE_CHOICES.map((obj) => obj.text); const COMPLETED = ["COMPLETED", "REJECTED"]; @@ -32,7 +32,6 @@ export default function BoardView() { }); const [boardFilter, setBoardFilter] = useState(ACTIVE); // eslint-disable-next-line - const [isLoading, setIsLoading] = useState(false); const appliedFilters = formatFilter(qParams); const { t } = useTranslation(); @@ -42,11 +41,11 @@ export default function BoardView() { }; return ( -
+
- - -
- {isLoading ? ( - - ) : ( - boardFilter.map((board) => ( - + title={} + sections={boardFilter.map((board) => ({ + id: board, + title: ( +

+ {board}{" "} + { + const { data } = await request( + routes.downloadResourceRequests, + { + query: { + ...formatFilter({ ...qParams, status: board }), + csv: true, + }, + }, + ); + return data ?? null; + }} + filenamePrefix={`resource_requests_${board}`} /> - )) - )} -

-
+ + ), + fetchOptions: (id) => ({ + route: routes.listResourceRequests, + options: { + query: formatFilter({ + ...qParams, + status: id, + }), + }, + }), + }))} + onDragEnd={(result) => { + if (result.source.droppableId !== result.destination?.droppableId) + navigate( + `/resource/${result.draggableId}/update?status=${result.destination?.droppableId}`, + ); + }} + itemRender={(resource) => ( +
+
+
+
+
+ {resource.title} +
+
+
+ {resource.emergency && ( + + {t("emergency")} + + )} +
+
+
+ {( + [ + { + title: "origin_facility", + icon: "l-plane-departure", + data: resource.origin_facility_object.name, + }, + { + title: "resource_approving_facility", + icon: "l-user-check", + data: resource.approving_facility_object?.name, + }, + { + title: "assigned_facility", + icon: "l-plane-arrival", + data: + resource.assigned_facility_object?.name || + t("yet_to_be_decided"), + }, + { + title: "last_modified", + icon: "l-stopwatch", + data: formatDateTime(resource.modified_date), + className: dayjs() + .subtract(2, "hours") + .isBefore(resource.modified_date) + ? "text-secondary-900" + : "rounded bg-red-500 border border-red-600 text-white w-full font-bold", + }, + { + title: "assigned_to", + icon: "l-user", + data: resource.assigned_to_object + ? formatName(resource.assigned_to_object) + + " - " + + resource.assigned_to_object.user_type + : undefined, + }, + ] as const + ) + .filter((d) => d.data) + .map((datapoint, i) => ( +
+
+ +
+
+ {datapoint.data} +
+
+ ))} +
+
+
+ + {t("all_details")} + +
+
+ )} + />
); diff --git a/src/Components/Resource/ResourceDetails.tsx b/src/Components/Resource/ResourceDetails.tsx index de024f46f41..50e572f5680 100644 --- a/src/Components/Resource/ResourceDetails.tsx +++ b/src/Components/Resource/ResourceDetails.tsx @@ -253,7 +253,7 @@ export default function ResourceDetails(props: { id: string }) {
{data.title || "--"}
Update Status/Details diff --git a/src/Components/Shifting/BoardView.tsx b/src/Components/Shifting/BoardView.tsx index dbd911483dc..f83e0a4974e 100644 --- a/src/Components/Shifting/BoardView.tsx +++ b/src/Components/Shifting/BoardView.tsx @@ -7,25 +7,26 @@ import BadgesList from "./BadgesList"; import { ExportButton } from "../Common/Export"; import ListFilter from "./ListFilter"; import SearchInput from "../Form/SearchInput"; -import ShiftingBoard from "./ShiftingBoard"; import { formatFilter } from "./Commons"; -import { navigate } from "raviger"; +import { Link, navigate } from "raviger"; import useFilters from "../../Common/hooks/useFilters"; -import { useLayoutEffect, useRef, useState } from "react"; +import { useState } from "react"; import { useTranslation } from "react-i18next"; -import withScrolling from "react-dnd-scrolling"; import ButtonV2 from "../Common/components/ButtonV2"; import { AdvancedFilterButton } from "../../CAREUI/interactive/FiltersSlideover"; import CareIcon from "../../CAREUI/icons/CareIcon"; import Tabs from "../Common/components/Tabs"; import careConfig from "@careConfig"; +import KanbanBoard from "../Kanban/Board"; +import { classNames, formatDateTime, formatName } from "../../Utils/utils"; +import dayjs from "dayjs"; +import ConfirmDialog from "../Common/ConfirmDialog"; +import { ShiftingModel } from "../Facility/models"; +import useAuthUser from "../../Common/hooks/useAuthUser"; import request from "../../Utils/request/request"; import routes from "../../Redux/api"; - -import Loading from "@/Components/Common/Loading"; import PageTitle from "@/Components/Common/PageTitle"; -const ScrollingComponent = withScrolling("div"); export default function BoardView() { const { qParams, updateQuery, FilterBadges, advancedFilter } = useFilters({ @@ -33,6 +34,26 @@ export default function BoardView() { cacheBlacklist: ["patient_name"], }); + const [modalFor, setModalFor] = useState<{ + externalId?: string; + loading: boolean; + }>({ + externalId: undefined, + loading: false, + }); + + const authUser = useAuthUser(); + + const handleTransferComplete = async (shift: any) => { + setModalFor({ ...modalFor, loading: true }); + await request(routes.completeTransfer, { + pathParams: { externalId: shift.external_id }, + }); + navigate( + `/facility/${shift.assigned_facility}/patient/${shift.patient}/consultation`, + ); + }; + const shiftStatusOptions = careConfig.wartimeShifting ? SHIFTING_CHOICES_WARTIME : SHIFTING_CHOICES_PEACETIME; @@ -55,79 +76,10 @@ export default function BoardView() { ); const [boardFilter, setBoardFilter] = useState(activeBoards); - const [isLoading] = useState(false); const { t } = useTranslation(); - const containerRef = useRef(null); - const [containerHeight, setContainerHeight] = useState(0); - const [isLeftScrollable, setIsLeftScrollable] = useState(false); - const [isRightScrollable, setIsRightScrollable] = useState(false); - - useLayoutEffect(() => { - const container = containerRef.current; - - if (!container) return; - - const handleScroll = () => { - setIsLeftScrollable(container.scrollLeft > 0); - setIsRightScrollable( - container.scrollLeft + container.clientWidth < - container.scrollWidth - 10, - ); - }; - - container.addEventListener("scroll", handleScroll); - - handleScroll(); - - return () => { - container.removeEventListener("scroll", handleScroll); - }; - }, []); - - const handleOnClick = (direction: "right" | "left") => { - const container = containerRef.current; - if (direction === "left" ? !isLeftScrollable : !isRightScrollable) return; - - if (container) { - const scrollAmount = 300; - const currentScrollLeft = container.scrollLeft; - - if (direction === "left") { - container.scrollTo({ - left: currentScrollLeft - scrollAmount, - behavior: "smooth", - }); - } else if (direction === "right") { - container.scrollTo({ - left: currentScrollLeft + scrollAmount, - behavior: "smooth", - }); - } - } - }; - - const renderArrowIcons = (direction: "right" | "left") => { - const isIconEnable = - direction === "left" ? isLeftScrollable : isRightScrollable; - return ( - isIconEnable && ( -
- handleOnClick(direction)} - /> -
- ) - ); - }; return ( -
+
- - -
- {isLoading ? ( - - ) : ( - <> - {renderArrowIcons("left")} -
- {boardFilter.map((board) => ( - - ))} + + title={} + sections={boardFilter.map((board) => ({ + id: board.text, + title: ( +

+ {board.label || board.text}{" "} + { + const { data } = await request(routes.downloadShiftRequests, { + query: { ...formatFilter(qParams), csv: true }, + }); + return data ?? null; + }} + filenamePrefix={`shift_requests_${board.label || board.text}`} + /> +

+ ), + fetchOptions: (id) => ({ + route: routes.listShiftRequests, + options: { + query: formatFilter({ + ...qParams, + status: id, + }), + }, + }), + }))} + onDragEnd={(result) => { + if (result.source.droppableId !== result.destination?.droppableId) + navigate( + `/shifting/${result.draggableId}/update?status=${result.destination?.droppableId}`, + ); + }} + itemRender={(shift) => ( +
+
+
+
+
+ {shift.patient_object.name} +
+
+ {shift.patient_object.age} old +
+
+
+ {shift.emergency && ( + + {t("emergency")} + + )} +
- {renderArrowIcons("right")} - - )} -
- +
+ {( + [ + { + title: "phone_number", + icon: "l-mobile-android", + data: shift.patient_object.phone_number, + }, + { + title: "origin_facility", + icon: "l-plane-departure", + data: shift.origin_facility_object.name, + }, + { + title: "shifting_approving_facility", + icon: "l-user-check", + data: careConfig.wartimeShifting + ? shift.shifting_approving_facility_object?.name + : undefined, + }, + { + title: "assigned_facility", + icon: "l-plane-arrival", + data: + shift.assigned_facility_external || + shift.assigned_facility_object?.name || + t("yet_to_be_decided"), + }, + { + title: "last_modified", + icon: "l-stopwatch", + data: formatDateTime(shift.modified_date), + className: dayjs() + .subtract(2, "hours") + .isBefore(shift.modified_date) + ? "text-secondary-900" + : "rounded bg-red-500 border border-red-600 text-white w-full font-bold", + }, + { + title: "patient_address", + icon: "l-home", + data: shift.patient_object.address, + }, + { + title: "assigned_to", + icon: "l-user", + data: shift.assigned_to_object + ? formatName(shift.assigned_to_object) + + " - " + + shift.assigned_to_object.user_type + : undefined, + }, + { + title: "patient_state", + icon: "l-map-marker", + data: shift.patient_object.state_object?.name, + }, + ] as const + ) + .filter((d) => d.data) + .map((datapoint, i) => ( +
+
+ +
+
+ {datapoint.data} +
+
+ ))} +
+
+
+ + {t("all_details")} + + + {shift.status === "COMPLETED" && shift.assigned_facility && ( + <> + + + + setModalFor({ externalId: undefined, loading: false }) + } + action={t("confirm")} + onConfirm={() => handleTransferComplete(shift)} + > +

+ {t("redirected_to_create_consultation")} +

+
+ + )} +
+
+ )} + />
); diff --git a/src/Components/Shifting/ShiftingBoard.tsx b/src/Components/Shifting/ShiftingBoard.tsx deleted file mode 100644 index 6f2eb3b77a3..00000000000 --- a/src/Components/Shifting/ShiftingBoard.tsx +++ /dev/null @@ -1,395 +0,0 @@ -import { - Dispatch, - SetStateAction, - useEffect, - useLayoutEffect, - useRef, - useState, -} from "react"; -import { classNames, formatDateTime, formatName } from "../../Utils/utils"; -import { useDrag, useDrop } from "react-dnd"; -import ButtonV2 from "../Common/components/ButtonV2"; -import ConfirmDialog from "../Common/ConfirmDialog"; -import { navigate } from "raviger"; -import { useTranslation } from "react-i18next"; -import { ExportButton } from "../Common/Export"; -import dayjs from "../../Utils/dayjs"; -import useAuthUser from "../../Common/hooks/useAuthUser"; -import request from "../../Utils/request/request"; -import routes from "../../Redux/api"; -import useQuery from "../../Utils/request/useQuery"; -import { PaginatedResponse } from "../../Utils/request/types"; -import { IShift } from "./models"; -import CareIcon from "../../CAREUI/icons/CareIcon"; -import careConfig from "@careConfig"; - -interface boardProps { - board: string; - title?: string; - filterProp: any; - formatFilter: any; - setContainerHeight: Dispatch>; - containerHeight: number; -} - -const ShiftCard = ({ shift, filter }: any) => { - const [modalFor, setModalFor] = useState({ - externalId: undefined, - loading: false, - }); - const [{ isDragging }, drag] = useDrag(() => ({ - type: "shift-card", - item: shift, - collect: (monitor) => ({ isDragging: !!monitor.isDragging() }), - })); - const authUser = useAuthUser(); - const { t } = useTranslation(); - - const handleTransferComplete = async (shift: any) => { - setModalFor({ ...modalFor, loading: true }); - await request(routes.completeTransfer, { - pathParams: { externalId: shift.external_id }, - }); - navigate( - `/facility/${shift.assigned_facility}/patient/${shift.patient}/consultation`, - ); - }; - return ( -
-
-
-
-
-
- {shift.patient_object.name} - {shift.patient_object.age} -
-
- {shift.emergency && ( - - {t("emergency")} - - )} -
-
-
-
-
- -
- {shift.patient_object.phone_number || ""} -
- -
-
-
- -
- {(shift.origin_facility_object || {}).name} -
- -
- {careConfig.wartimeShifting && ( -
-
- -
- {(shift.shifting_approving_facility_object || {}).name} -
- -
- )} -
-
- - -
- {shift.assigned_facility_external || - shift.assigned_facility_object?.name || - t("yet_to_be_decided")} -
- -
- -
-
- -
- {formatDateTime(shift.modified_date) || "--"} -
- -
- -
-
- -
- {shift.patient_object.address || "--"} -
- -
- - {shift.assigned_to_object && ( -
-
- -
- {formatName(shift.assigned_to_object)} - {" - "} - {shift.assigned_to_object.user_type} -
- -
- )} - -
-
- -
- {shift.patient_object.state_object.name || "--"} -
- -
-
-
- -
- -
- {filter === "COMPLETED" && shift.assigned_facility && ( -
- setModalFor(shift.external_id)} - > - {t("transfer_to_receiving_facility")} - - - - setModalFor({ externalId: undefined, loading: false }) - } - action={t("confirm")} - onConfirm={() => handleTransferComplete(shift)} - > -

- {t("redirected_to_create_consultation")} -

-
-
- )} -
-
-
- ); -}; - -export default function ShiftingBoard({ - board, - title, - filterProp, - formatFilter, - setContainerHeight, - containerHeight, -}: boardProps) { - const containerRef = useRef(null); - const [offset, setOffSet] = useState(0); - const [pages, setPages] = useState[]>([]); - const [isLoading, setIsLoading] = useState(true); - const [{ isOver }, drop] = useDrop(() => ({ - accept: "shift-card", - drop: (item: any) => { - if (item.status !== board) { - navigate(`/shifting/${item.id}/update?status=${board}`); - } - }, - collect: (monitor) => ({ isOver: !!monitor.isOver() }), - })); - - const query = useQuery(routes.listShiftRequests, { - query: formatFilter({ - ...filterProp, - status: board, - }), - onResponse: ({ res, data: listShiftData }) => { - setIsLoading(false); - if (res?.ok && listShiftData) { - setPages((prev) => [...prev, listShiftData]); - } - }, - }); - - useEffect(() => { - setPages([]); - setIsLoading(true); - query.refetch(); - }, [ - filterProp.facility, - filterProp.origin_facility, - filterProp.shifting_approving_facility, - filterProp.assigned_facility, - filterProp.emergency, - filterProp.is_up_shift, - filterProp.patient_name, - filterProp.created_date_before, - filterProp.created_date_after, - filterProp.modified_date_before, - filterProp.modified_date_after, - filterProp.patient_phone_number, - filterProp.ordering, - filterProp.is_kasp, - filterProp.assigned_to, - filterProp.is_antenatal, - filterProp.breathlessness_level, - ]); - - const handlePagination = async () => { - setIsLoading(true); - setOffSet(offset + 14); - const { res, data: newPageData } = await request(routes.listShiftRequests, { - query: formatFilter({ - ...filterProp, - status: board, - offset: offset, - }), - }); - if (res?.ok && newPageData) { - setPages((prev) => [...prev, newPageData]); - } - setIsLoading(false); - }; - const { t } = useTranslation(); - - const patientFilter = (filter: string) => { - return pages - .flatMap((p) => p.results) - .filter(({ status }) => status === filter) - .map((shift: any) => ( - - )); - }; - - useLayoutEffect(() => { - const container = containerRef.current; - if (container) { - const { height } = container.getBoundingClientRect(); - containerHeight < height && setContainerHeight(height); - } - }, [containerRef.current, pages.flatMap((p) => p.results).length]); - - return ( -
-
-
-

- {title || board}{" "} - { - const { data } = await request(routes.downloadShiftRequests, { - query: { - ...formatFilter({ ...filterProp, status: board }), - csv: true, - }, - }); - return data ?? null; - }} - filenamePrefix={`shift_requests_${board}`} - /> -

- - {pages[0] ? pages[0].count : "..."} - -
-
-
- {pages[0]?.count > 0 - ? patientFilter(board) - : !isLoading && ( -

{t("no_patients_to_show")}

- )} - {isLoading ? ( -
-
-
-
-
-
-
-
-
-
-
-
-
- ) : ( - pages.at(-1)?.next && ( - handlePagination()} className="m-2 block"> - Load More - - ) - )} -
-
- ); -} diff --git a/src/Locale/en.json b/src/Locale/en.json index 49dfda28646..33755045d0b 100644 --- a/src/Locale/en.json +++ b/src/Locale/en.json @@ -940,7 +940,7 @@ "modified_date": "Modified Date", "no_patients_to_show": "No patients to show.", "shifting_status": "Shifting status", - "transfer_to_receiving_facility": "TRANSFER TO RECEIVING FACILITY", + "transfer_to_receiving_facility": "Transfer to receiving facility", "confirm_transfer_complete": "Confirm Transfer Complete!", "mark_transfer_complete_confirmation": "Are you sure you want to mark this transfer as complete? The Origin facility will no longer have access to this patient", "board_view": "Board View", @@ -1021,6 +1021,8 @@ "date_declared_positive": "Date of declaring positive", "date_of_result": "Covid confirmation date", "is_vaccinated": "Whether vaccinated", + "resource_origin_facility": "Origin Facility", + "resource_approving_facility" : "Resource approving facility", "consultation_not_filed": "You have not filed any consultation for this patient yet.", "consultation_not_filed_description": "Please file a consultation for this patient to continue.", "camera_locking_error": "An error occurred while locking the camera", @@ -1038,5 +1040,7 @@ "save_current_position_to_preset": "Save current position to selected preset", "change_camera_position_and_update_preset": "Change camera position to update preset", "loading_preset": "Loading Preset", - "retry": "Retry" + "retry": "Retry", + "width": "Width ({{unit}})", + "length": "Length ({{unit}})" } diff --git a/src/Routers/routes/ResourceRoutes.tsx b/src/Routers/routes/ResourceRoutes.tsx index 8408ab4d79d..6636d0d83ea 100644 --- a/src/Routers/routes/ResourceRoutes.tsx +++ b/src/Routers/routes/ResourceRoutes.tsx @@ -1,5 +1,3 @@ -import { DndProvider } from "react-dnd"; -import { HTML5Backend } from "react-dnd-html5-backend"; import ResourceDetails from "../../Components/Resource/ResourceDetails"; import { ResourceDetailsUpdate } from "../../Components/Resource/ResourceDetailsUpdate"; import ListView from "../../Components/Resource/ListView"; @@ -12,11 +10,7 @@ const getDefaultView = () => export default { "/resource": () => , - "/resource/board": () => ( - - - - ), + "/resource/board": () => , "/resource/list": () => , "/resource/:id": ({ id }: DetailRoute) => , "/resource/:id/update": ({ id }: DetailRoute) => ( diff --git a/src/Routers/routes/ShiftingRoutes.tsx b/src/Routers/routes/ShiftingRoutes.tsx index 9b20b4a1a0b..f2e12de4f25 100644 --- a/src/Routers/routes/ShiftingRoutes.tsx +++ b/src/Routers/routes/ShiftingRoutes.tsx @@ -1,5 +1,3 @@ -import { DndProvider } from "react-dnd"; -import { HTML5Backend } from "react-dnd-html5-backend"; import { ShiftCreate } from "../../Components/Patient/ShiftCreate"; import ShiftDetails from "../../Components/Shifting/ShiftDetails"; import { ShiftDetailsUpdate } from "../../Components/Shifting/ShiftDetailsUpdate"; @@ -12,11 +10,7 @@ const getDefaultView = () => export default { "/shifting": () => , - "/shifting/board": () => ( - - - - ), + "/shifting/board": () => , "/shifting/list": () => , "/shifting/:id": ({ id }: any) => , "/shifting/:id/update": ({ id }: any) => , diff --git a/src/Utils/AutoSave.tsx b/src/Utils/AutoSave.tsx index da330a3fc6a..dd251f5bbb7 100644 --- a/src/Utils/AutoSave.tsx +++ b/src/Utils/AutoSave.tsx @@ -1,4 +1,12 @@ -import { useReducer, useEffect, useRef, useState, Dispatch } from "react"; +import React, { + useReducer, + useEffect, + useRef, + useState, + Dispatch, + useContext, + ReactNode, +} from "react"; import { Button } from "../Components/ui/button"; import { FormAction, FormReducer, FormState } from "../Components/Form/Utils"; import { relativeTime } from "./utils"; @@ -81,9 +89,20 @@ export function useAutoSaveState(initialState: any) { return [state, setState]; } +type RestoreDraftContextValue = { + handleDraftSelect: (formState: any) => void; + draftStarted: boolean; + drafts: Draft[]; +}; + +const RestoreDraftContext = + React.createContext(null); + export function DraftSection(props: { handleDraftSelect: (formState: any) => void; formData: any; + hidden?: boolean; + children?: ReactNode; }) { const { handleDraftSelect } = props; const [drafts, setDrafts] = useState([]); @@ -123,32 +142,56 @@ export function DraftSection(props: { }, []); return ( - <> - {drafts && drafts.length > 0 && ( + + {!props.hidden && drafts && drafts.length > 0 && (
- +
)} - + {props.children} +
); } + +export const RestoreDraftButton = () => { + const ctx = useContext(RestoreDraftContext); + + if (!ctx) { + throw new Error( + "RestoreDraftButton must be used within a RestoreDraftProvider", + ); + } + + const { handleDraftSelect, draftStarted, drafts } = ctx; + + if (!(drafts && drafts.length > 0)) { + return null; + } + + return ( + + ); +};