diff --git a/README.md b/README.md
index 002afc979bc..7f2c3e926bd 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=coronasafe_care_fe&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=coronasafe_care_fe)
![Code scanning - action](https://github.com/coronasafe/care_fe/workflows/Code%20scanning%20-%20action/badge.svg)
![OSSAR](https://github.com/coronasafe/care_fe/workflows/OSSAR/badge.svg)
-[![Cypress Tests](https://github.com/coronasafe/care_fe/actions/workflows/cypress.yaml/badge.svg)](https://github.com/coronasafe/care_fe/actions/workflows/cypress.yaml)
+[![Cypress Tests](https://img.shields.io/endpoint?url=https://cloud.cypress.io/badge/simple/wf7d2m/develop&style=flat&logo=cypress)](https://cloud.cypress.io/projects/wf7d2m/runs)
![Staging Release](https://github.com/coronasafe/care_fe/workflows/CARE%20Develop%20Registry/badge.svg)
![Production Release](https://github.com/coronasafe/care_fe/workflows/Production%20Release/badge.svg)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/200482ab117e4b5397ff3f5ae5719aa2)](https://www.codacy.com/gh/coronasafe/care_fe?utm_source=github.com&utm_medium=referral&utm_content=coronasafe/care_fe&utm_campaign=Badge_Grade)
@@ -50,7 +50,7 @@ Once the development server has started, open [localhost:4000](http://localhost:
Authenticate to staging API with any of the following credentials
```yaml
-- username: devdistrictadmin
+- username: dev-districtadmin
password: Coronasafe@123
role: District Admin
diff --git a/cypress/e2e/facility_spec/facility.cy.ts b/cypress/e2e/facility_spec/facility.cy.ts
deleted file mode 100644
index f2ff847c9d9..00000000000
--- a/cypress/e2e/facility_spec/facility.cy.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-// FacilityCreation
-import { cy, describe, before, beforeEach, it, afterEach } from "local-cypress";
-import FacilityPage from "../../pageobject/Facility/FacilityCreation";
-import LoginPage from "../../pageobject/Login/LoginPage";
-
-describe("Facility Creation", () => {
- let facilityUrl: string;
- const facilityPage = new FacilityPage();
- const loginPage = new LoginPage();
-
- before(() => {
- loginPage.loginAsDisctrictAdmin();
- cy.saveLocalStorage();
- });
-
- beforeEach(() => {
- cy.viewport(1280, 720);
- cy.restoreLocalStorage();
- cy.awaitUrl("/facility");
- });
-
- it("Create a new facility", () => {
- facilityPage.visitCreateFacilityPage();
- facilityPage.fillFacilityName("cypress facility");
- facilityPage.fillPincode("682001");
- facilityPage.selectState("Kerala");
- facilityPage.selectDistrict("Ernakulam");
- facilityPage.selectLocalBody("Aluva");
- facilityPage.selectWard("4");
- facilityPage.fillAddress("Cypress Address");
- facilityPage.fillPhoneNumber("9898469865");
- facilityPage.submitForm();
-
- facilityPage.selectBedType("Non-Covid Oxygen beds");
- facilityPage.fillTotalCapacity("10");
- facilityPage.fillCurrentlyOccupied("5");
- facilityPage.saveAndExitBedCapacityForm();
-
- facilityPage.selectAreaOfSpecialization("General Medicine");
- facilityPage.fillDoctorCount("5");
- facilityPage.saveAndExitDoctorForm();
- facilityPage.verifyfacilitynewurl();
- cy.url().then((newUrl) => {
- facilityUrl = newUrl;
- });
- });
-
- it("Update the existing facility", () => {
- facilityPage.visitUpdateFacilityPage(facilityUrl);
- facilityPage.clickManageFacilityDropdown();
- facilityPage.clickUpdateFacilityOption();
- facilityPage.clickUpdateFacilityType();
- facilityPage.fillFacilityName("cypress facility updated");
- facilityPage.fillAddress("Cypress Facility Updated Address");
- facilityPage.fillOxygenCapacity("100");
- facilityPage.fillExpectedOxygenRequirement("80");
- facilityPage.selectLocation("Kochi, Kerala");
- facilityPage.submitForm();
-
- cy.url().should("not.include", "/update");
- });
-
- it("Configure the existing facility", () => {
- facilityPage.visitUpdateFacilityPage(facilityUrl);
- facilityPage.clickManageFacilityDropdown();
- facilityPage.clickConfigureFacilityOption();
- facilityPage.fillMiddleWareAddress("dev_middleware.coronasafe.live");
- facilityPage.clickupdateMiddleWare();
- facilityPage.verifySuccessNotification("Facility updated successfully");
- });
-
- it("Delete a facility", () => {
- facilityPage.visitUpdateFacilityPage(facilityUrl);
- facilityPage.clickManageFacilityDropdown();
- facilityPage.clickDeleteFacilityOption();
- facilityPage.confirmDeleteFacility();
- });
-
- afterEach(() => {
- cy.saveLocalStorage();
- });
-});
diff --git a/cypress/e2e/facility_spec/facility_creation.cy.ts b/cypress/e2e/facility_spec/facility_creation.cy.ts
new file mode 100644
index 00000000000..cc2d1b7f921
--- /dev/null
+++ b/cypress/e2e/facility_spec/facility_creation.cy.ts
@@ -0,0 +1,304 @@
+// FacilityCreation
+import { cy, describe, before, beforeEach, it, afterEach } from "local-cypress";
+import FacilityPage from "../../pageobject/Facility/FacilityCreation";
+import LoginPage from "../../pageobject/Login/LoginPage";
+import FacilityHome from "../../pageobject/Facility/FacilityHome";
+import ManageUserPage from "../../pageobject/Users/ManageUserPage";
+import { UserCreationPage } from "../../pageobject/Users/UserCreation";
+
+describe("Facility Creation", () => {
+ let facilityUrl1: string;
+ const facilityPage = new FacilityPage();
+ const loginPage = new LoginPage();
+ const facilityHome = new FacilityHome();
+ const manageUserPage = new ManageUserPage();
+ const userCreationPage = new UserCreationPage();
+ const facilityFeature = [
+ "CT Scan",
+ "X-Ray",
+ "Maternity Care",
+ "Neonatal Care",
+ "Operation Theater",
+ "Blood Bank",
+ ];
+ const bedCapacity = "10";
+ const bedOccupancy = "5";
+ const oxygenCapacity = "100";
+ const oxygenExpected = "80";
+ const totalCapacity = "20";
+ const totalOccupancy = "10";
+ const doctorCapacity = "5";
+ const totalDoctor = "10";
+ const facilityName = "cypress facility";
+ const facilityName2 = "Dummy Facility 1";
+ const facilityAddress = "cypress address";
+ const facilityUpdateAddress = "cypress updated address";
+ const facilityNumber = "9898469865";
+ const triageDate = "02122023";
+ const initialTriageValue = "60";
+ const modifiedTriageValue = "50";
+ const facilityErrorMessage = [
+ "Required",
+ "Invalid Pincode",
+ "Required",
+ "Required",
+ "Required",
+ "Required",
+ "Required",
+ "Required",
+ "Invalid Phone Number",
+ ];
+ const bedErrorMessage = [
+ "Field is required",
+ "Total capacity cannot be 0",
+ "Field is required",
+ ];
+ const doctorErrorMessage = ["Field is required", "Field is required"];
+ const triageErrorMessage = ["Field is required"];
+
+ before(() => {
+ loginPage.loginAsDisctrictAdmin();
+ cy.saveLocalStorage();
+ });
+
+ beforeEach(() => {
+ cy.viewport(1280, 720);
+ cy.restoreLocalStorage();
+ cy.awaitUrl("/facility");
+ });
+
+ it("Verify Facility Triage Function", () => {
+ // mandatory field error throw
+ manageUserPage.typeFacilitySearch(facilityName2);
+ facilityPage.verifyFacilityBadgeContent(facilityName2);
+ manageUserPage.assertFacilityInCard(facilityName2);
+ facilityHome.verifyURLContains(facilityName2);
+ facilityPage.visitAlreadyCreatedFacility();
+ facilityPage.scrollToFacilityTriage();
+ facilityPage.clickAddFacilityTriage();
+ manageUserPage.clickSubmit();
+ userCreationPage.verifyErrorMessages(triageErrorMessage);
+ // create a entry and verify reflection
+ facilityPage.fillEntryDate(triageDate);
+ facilityPage.fillTriageEntryFields(
+ initialTriageValue,
+ initialTriageValue,
+ initialTriageValue,
+ initialTriageValue,
+ initialTriageValue
+ );
+ manageUserPage.clickSubmit();
+ // edit the entry and verify reflection
+ facilityPage.scrollToFacilityTriage();
+ facilityPage.verifyTriageTableContains(initialTriageValue);
+ facilityPage.clickEditButton();
+ facilityPage.fillTriageEntryFields(
+ modifiedTriageValue,
+ modifiedTriageValue,
+ modifiedTriageValue,
+ modifiedTriageValue,
+ modifiedTriageValue
+ );
+ manageUserPage.clickSubmit();
+ facilityPage.scrollToFacilityTriage();
+ facilityPage.verifyTriageTableContains(modifiedTriageValue);
+ // validate error of filling data on same date already data exist and verify reflection
+ facilityPage.scrollToFacilityTriage();
+ facilityPage.clickAddFacilityTriage();
+ facilityPage.fillEntryDate(triageDate);
+ facilityPage.clickButtonsMultipleTimes("button#submit");
+ });
+
+ it("Create a new facility with multiple bed and doctor capacity", () => {
+ // create facility with multiple capacity and verify form error message for facility form
+ facilityPage.visitCreateFacilityPage();
+ facilityPage.submitForm();
+ userCreationPage.verifyErrorMessages(facilityErrorMessage);
+ facilityPage.fillFacilityName(facilityName);
+ facilityPage.clickfacilityfeatureoption();
+ facilityFeature.forEach((featureText) => {
+ cy.get("[role='option']").contains(featureText).click();
+ });
+ facilityPage.fillPincode("682001");
+ facilityPage.selectLocalBody("Aluva");
+ facilityPage.selectWard("4");
+ facilityPage.fillAddress(facilityAddress);
+ facilityPage.fillPhoneNumber(facilityNumber);
+ facilityPage.fillOxygenCapacity(oxygenCapacity);
+ facilityPage.fillExpectedOxygenRequirement(oxygenExpected);
+ facilityPage.fillBTypeCylinderCapacity(oxygenCapacity);
+ facilityPage.fillExpectedBTypeCylinderRequirement(oxygenExpected);
+ facilityPage.fillCTypeCylinderCapacity(oxygenCapacity);
+ facilityPage.fillExpectedCTypeCylinderRequirement(oxygenExpected);
+ facilityPage.fillDTypeCylinderCapacity(oxygenCapacity);
+ facilityPage.fillExpectedDTypeCylinderRequirement(oxygenExpected);
+ facilityPage.selectLocation("Kochi, Kerala");
+ facilityPage.submitForm();
+ // create multiple bed capacity and verify card reflection
+ facilityPage.selectBedType("Oxygen beds");
+ facilityPage.fillTotalCapacity(bedCapacity);
+ facilityPage.fillCurrentlyOccupied(bedOccupancy);
+ facilityPage.clickbedcapcityaddmore();
+ facilityPage.selectBedType("Ordinary Bed");
+ facilityPage.fillTotalCapacity(bedCapacity);
+ facilityPage.fillCurrentlyOccupied(bedOccupancy);
+ facilityPage.clickbedcapcityaddmore();
+ facilityPage.getTotalBedCapacity().contains(totalCapacity);
+ facilityPage.getTotalBedCapacity().contains(totalOccupancy);
+ facilityPage.clickcancelbutton();
+ // create multiple bed capacity and verify card reflection
+ facilityPage.selectAreaOfSpecialization("General Medicine");
+ facilityPage.fillDoctorCount(doctorCapacity);
+ facilityPage.clickdoctorcapacityaddmore();
+ facilityPage.selectAreaOfSpecialization("Pulmonology");
+ facilityPage.fillDoctorCount(doctorCapacity);
+ facilityPage.clickdoctorcapacityaddmore();
+ facilityPage.getTotalDoctorCapacity().contains(doctorCapacity);
+ facilityPage.clickcancelbutton();
+ facilityPage.verifyfacilitynewurl();
+ // verify the facility card
+ facilityPage.getFacilityName().contains(facilityName).should("be.visible");
+ facilityPage
+ .getAddressDetailsView()
+ .contains(facilityAddress)
+ .should("be.visible");
+ facilityPage
+ .getPhoneNumberView()
+ .contains(facilityNumber)
+ .should("be.visible");
+ facilityPage
+ .getFacilityAvailableFeatures()
+ .invoke("text")
+ .then((text) => {
+ facilityFeature.forEach((feature) => {
+ expect(text).to.contain(feature);
+ });
+ });
+ facilityPage.getFacilityOxygenInfo().scrollIntoView();
+ facilityPage
+ .getFacilityOxygenInfo()
+ .contains(oxygenCapacity)
+ .should("be.visible");
+ facilityPage.getFacilityTotalBedCapacity().scrollIntoView();
+ facilityPage.getFacilityTotalBedCapacity().contains(totalCapacity);
+ facilityPage.getFacilityTotalBedCapacity().contains(totalOccupancy);
+ facilityPage.getFacilityTotalDoctorCapacity().scrollIntoView();
+ facilityPage.getFacilityTotalDoctorCapacity().contains(totalDoctor);
+ });
+
+ it("Create a new facility with single bed and doctor capacity", () => {
+ facilityPage.visitCreateFacilityPage();
+ facilityPage.fillFacilityName(facilityName);
+ facilityPage.fillPincode("682001");
+ facilityPage.selectLocalBody("Aluva");
+ facilityPage.selectWard("4");
+ facilityPage.fillAddress(facilityAddress);
+ facilityPage.fillPhoneNumber(facilityNumber);
+ facilityPage.submitForm();
+ // add the bed capacity
+ facilityPage.selectBedType("Oxygen beds");
+ facilityPage.fillTotalCapacity(oxygenCapacity);
+ facilityPage.fillCurrentlyOccupied(oxygenExpected);
+ facilityPage.saveAndExitBedCapacityForm();
+ // add the doctor capacity
+ facilityPage.selectAreaOfSpecialization("General Medicine");
+ facilityPage.fillDoctorCount(doctorCapacity);
+ facilityPage.saveAndExitDoctorForm();
+ facilityPage.verifyfacilitynewurl();
+ // verify the created facility details
+ facilityPage.getFacilityName().contains(facilityName).should("be.visible");
+ facilityPage
+ .getAddressDetailsView()
+ .contains(facilityAddress)
+ .should("be.visible");
+ facilityPage
+ .getPhoneNumberView()
+ .contains(facilityNumber)
+ .should("be.visible");
+ // verify the facility homepage
+ cy.visit("/facility");
+ manageUserPage.typeFacilitySearch(facilityName);
+ facilityPage.verifyFacilityBadgeContent(facilityName);
+ manageUserPage.assertFacilityInCard(facilityName);
+ facilityHome.verifyURLContains(facilityName);
+ });
+
+ it("Create a new facility with no bed and doctor capacity", () => {
+ facilityPage.visitCreateFacilityPage();
+ facilityPage.fillFacilityName(facilityName);
+ facilityPage.fillPincode("682001");
+ facilityPage.selectLocalBody("Aluva");
+ facilityPage.selectWard("4");
+ facilityPage.fillAddress(facilityAddress);
+ facilityPage.fillPhoneNumber(facilityNumber);
+ facilityPage.submitForm();
+ // add no bed capacity and verify form error message
+ facilityPage.isVisibleselectBedType();
+ facilityPage.saveAndExitBedCapacityForm();
+ userCreationPage.verifyErrorMessages(bedErrorMessage);
+ facilityPage.clickcancelbutton();
+ // add no doctor capacity and verify form error message
+ facilityPage.isVisibleAreaOfSpecialization();
+ facilityPage.clickdoctorcapacityaddmore();
+ userCreationPage.verifyErrorMessages(doctorErrorMessage);
+ facilityPage.clickcancelbutton();
+ cy.url().then((newUrl) => {
+ facilityUrl1 = newUrl;
+ });
+ // verify the created facility details
+ facilityPage.getFacilityName().contains(facilityName).should("be.visible");
+ facilityPage
+ .getAddressDetailsView()
+ .contains(facilityAddress)
+ .should("be.visible");
+ facilityPage
+ .getPhoneNumberView()
+ .contains(facilityNumber)
+ .should("be.visible");
+ });
+
+ it("Update the existing facility", () => {
+ // update a existing dummy data facility
+ facilityPage.visitUpdateFacilityPage(facilityUrl1);
+ facilityPage.clickManageFacilityDropdown();
+ facilityPage.clickUpdateFacilityOption();
+ facilityPage.clickUpdateFacilityType("Govt Hospital");
+ facilityPage.fillAddress(facilityUpdateAddress);
+ facilityPage.fillOxygenCapacity(oxygenCapacity);
+ facilityPage.fillExpectedOxygenRequirement(oxygenExpected);
+ facilityPage.selectLocation("Kochi, Kerala");
+ facilityPage.submitForm();
+ cy.url().should("not.include", "/update");
+ // verify the updated data
+ facilityPage.getFacilityOxygenInfo().scrollIntoView();
+ facilityPage
+ .getFacilityOxygenInfo()
+ .contains(oxygenCapacity)
+ .should("be.visible");
+ facilityPage.getAddressDetailsView().scrollIntoView();
+ facilityPage
+ .getAddressDetailsView()
+ .contains(facilityUpdateAddress)
+ .should("be.visible");
+ });
+
+ it("Configure the existing facility", () => {
+ facilityPage.visitUpdateFacilityPage(facilityUrl1);
+ facilityPage.clickManageFacilityDropdown();
+ facilityPage.clickConfigureFacilityOption();
+ facilityPage.fillMiddleWareAddress("dev_middleware.coronasafe.live");
+ facilityPage.clickupdateMiddleWare();
+ facilityPage.verifySuccessNotification("Facility updated successfully");
+ });
+
+ it("Delete a facility", () => {
+ facilityPage.visitUpdateFacilityPage(facilityUrl1);
+ facilityPage.clickManageFacilityDropdown();
+ facilityPage.clickDeleteFacilityOption();
+ facilityPage.confirmDeleteFacility();
+ });
+
+ afterEach(() => {
+ cy.saveLocalStorage();
+ });
+});
diff --git a/cypress/e2e/facility_spec/facility_homepage.cy.ts b/cypress/e2e/facility_spec/facility_homepage.cy.ts
index bf6ce12536e..3d916b4ba47 100644
--- a/cypress/e2e/facility_spec/facility_homepage.cy.ts
+++ b/cypress/e2e/facility_spec/facility_homepage.cy.ts
@@ -4,17 +4,22 @@ import LoginPage from "../../pageobject/Login/LoginPage";
import FacilityHome from "../../pageobject/Facility/FacilityHome";
import ManageUserPage from "../../pageobject/Users/ManageUserPage";
import FacilityPage from "../../pageobject/Facility/FacilityCreation";
+import { UserPage } from "../../pageobject/Users/UserSearch";
-describe("Facility Creation", () => {
+describe("Facility Homepage Function", () => {
const loginPage = new LoginPage();
const facilityHome = new FacilityHome();
const facilityPage = new FacilityPage();
const manageUserPage = new ManageUserPage();
+ const userPage = new UserPage();
const facilitiesAlias = "downloadFacilitiesCSV";
const capacitiesAlias = "downloadCapacitiesCSV";
const doctorsAlias = "downloadDoctorsCSV";
const triagesAlias = "downloadTriagesCSV";
const facilityname = "Dummy Facility 1";
+ const statename = "Kerala";
+ const district = "Ernakulam";
+ const facilitytype = "Private Hospital";
before(() => {
loginPage.loginAsDisctrictAdmin();
@@ -26,6 +31,23 @@ describe("Facility Creation", () => {
cy.awaitUrl("/facility");
});
+ it("Verify the functionality of advance filter", () => {
+ userPage.clickAdvancedFilters();
+ facilityPage.selectState(statename);
+ facilityPage.selectDistrict(district);
+ // facilityPage.selectLocalBody("Anthikad Grama"); current dummy data have issue in local body
+ facilityPage.clickUpdateFacilityType(facilitytype);
+ userPage.applyFilter();
+ facilityPage.verifyStateBadgeContent(statename);
+ facilityPage.verifyDistrictBadgeContent(district);
+ facilityPage.verifyFacilityTypeBadgeContent(facilitytype);
+ manageUserPage.assertFacilityInCard(facilityname);
+ userPage.clearFilters();
+ userPage.verifyDataTestIdNotVisible("State");
+ userPage.verifyDataTestIdNotVisible("District");
+ userPage.verifyDataTestIdNotVisible("Facility type");
+ });
+
it("Search a facility in homepage", () => {
manageUserPage.typeFacilitySearch(facilityname);
facilityPage.verifyFacilityBadgeContent(facilityname);
diff --git a/cypress/pageobject/Facility/FacilityCreation.ts b/cypress/pageobject/Facility/FacilityCreation.ts
index d27433f04e7..c13f5beac8e 100644
--- a/cypress/pageobject/Facility/FacilityCreation.ts
+++ b/cypress/pageobject/Facility/FacilityCreation.ts
@@ -17,11 +17,11 @@ class FacilityPage {
cy.get("#manage-facility-dropdown button").should("be.visible");
}
- clickUpdateFacilityType() {
+ clickUpdateFacilityType(facilityType) {
cy.get("#facility_type")
.click()
.then(() => {
- cy.get("[role='option']").contains("Request Approving Center").click();
+ cy.get("[role='option']").contains(facilityType).click();
});
}
@@ -70,6 +70,10 @@ class FacilityPage {
cy.get("[role='option']").contains(bedType).click();
}
+ isVisibleselectBedType() {
+ cy.get("div#bed-type button").should("be.visible");
+ }
+
fillTotalCapacity(capacity: string) {
cy.get("input#total-capacity").click().type(capacity);
}
@@ -87,6 +91,10 @@ class FacilityPage {
cy.get("[role='option']").contains(area).click();
}
+ isVisibleAreaOfSpecialization() {
+ cy.get("div#area-of-specialization button").should("be.visible");
+ }
+
fillDoctorCount(count: string) {
cy.get("input#count").click().type(count);
}
@@ -99,6 +107,33 @@ class FacilityPage {
cy.get("#expected_oxygen_requirement").click().clear().type(requirement);
}
+ fillBTypeCylinderCapacity(capacity: string) {
+ cy.get("#type_b_cylinders").click().clear().type(capacity);
+ }
+
+ fillExpectedBTypeCylinderRequirement(requirement: string) {
+ cy.get("#expected_type_b_cylinders").focus().clear();
+ cy.get("#expected_type_b_cylinders").focus().type(requirement);
+ }
+
+ fillCTypeCylinderCapacity(capacity: string) {
+ cy.get("#type_c_cylinders").click().clear().type(capacity);
+ }
+
+ fillExpectedCTypeCylinderRequirement(requirement: string) {
+ cy.get("#expected_type_c_cylinders").focus().clear();
+ cy.get("#expected_type_c_cylinders").focus().type(requirement);
+ }
+
+ fillDTypeCylinderCapacity(capacity: string) {
+ cy.get("#type_d_cylinders").click().clear().type(capacity);
+ }
+
+ fillExpectedDTypeCylinderRequirement(requirement: string) {
+ cy.get("#expected_type_d_cylinders").focus().clear();
+ cy.get("#expected_type_d_cylinders").focus().type(requirement);
+ }
+
saveAndExitDoctorForm() {
cy.intercept("GET", "**/api/v1/facility/**").as("createFacilities");
cy.get("button#save-and-exit").click();
@@ -138,6 +173,42 @@ class FacilityPage {
cy.get("#inventory-management").click();
}
+ getTotalBedCapacity() {
+ return cy.get("#total-bed-capacity");
+ }
+
+ getFacilityTotalBedCapacity() {
+ return cy.get("#facility-bed-capacity-details");
+ }
+
+ getFacilityTotalDoctorCapacity() {
+ return cy.get("#facility-doctor-capacity-details");
+ }
+
+ getTotalDoctorCapacity() {
+ return cy.get("#total-doctor-capacity");
+ }
+
+ getFacilityName() {
+ return cy.get("#facility-name");
+ }
+
+ getAddressDetailsView() {
+ return cy.get("#address-details-view");
+ }
+
+ getPhoneNumberView() {
+ return cy.get("#phone-number-view");
+ }
+
+ getFacilityAvailableFeatures() {
+ return cy.get("#facility-available-features");
+ }
+
+ getFacilityOxygenInfo() {
+ return cy.get("#facility-oxygen-info");
+ }
+
clickResourceRequestOption() {
cy.get("#resource-request").contains("Resource Request").click();
}
@@ -146,6 +217,69 @@ class FacilityPage {
cy.get("#delete-facility").contains("Delete Facility").click();
}
+ scrollToFacilityTriage() {
+ cy.get("#add-facility-triage").scrollIntoView();
+ }
+
+ fillTriageEntryFields(
+ visited,
+ homeQuarantine,
+ isolation,
+ referred,
+ confirmedPositive
+ ) {
+ cy.get("#num_patients_visited").clear().click().type(visited);
+ cy.get("#num_patients_home_quarantine")
+ .clear()
+ .click()
+ .type(homeQuarantine);
+ cy.get("#num_patients_isolation").clear().click().type(isolation);
+ cy.get("#num_patient_referred").clear().click().type(referred);
+ cy.get("#num_patient_confirmed_positive")
+ .clear()
+ .click()
+ .type(confirmedPositive);
+ }
+
+ fillEntryDate(date) {
+ cy.get("#entry_date").click();
+ cy.get("#date-input").click().type(date);
+ }
+
+ clickEditButton() {
+ cy.get("#edit-button").click();
+ }
+
+ clickButtonsMultipleTimes(selector) {
+ cy.get(selector).each(($button) => {
+ cy.wrap($button).click();
+ });
+ }
+
+ verifyTriageTableContains(value) {
+ cy.get("#triage-table").contains(value);
+ }
+
+ clickAddFacilityTriage() {
+ cy.get("#add-facility-triage").click();
+ }
+
+ clickfacilityfeatureoption() {
+ cy.get("#features").click();
+ }
+
+ clickbedcapcityaddmore() {
+ cy.get("#bed-capacity-save").click();
+ }
+
+ clickdoctorcapacityaddmore() {
+ cy.get("#doctor-save").click();
+ }
+
+ clickcancelbutton() {
+ cy.get("#cancel").click();
+ }
+
verifyfacilitynewurl() {
cy.url().should("match", /facility\/[a-z\d-]+/);
}
@@ -195,6 +329,18 @@ class FacilityPage {
);
}
+ verifyStateBadgeContent(expectedText: string) {
+ cy.get("[data-testid='State']").should("contain", expectedText);
+ }
+
+ verifyDistrictBadgeContent(expectedText: string) {
+ cy.get("[data-testid='District']").should("contain", expectedText);
+ }
+
+ verifyFacilityTypeBadgeContent(expectedText: string) {
+ cy.get("[data-testid='Facility type']").should("contain", expectedText);
+ }
+
verifyfacilitycreateassetredirection() {
cy.url().should("include", "/assets/new");
}
diff --git a/cypress/pageobject/Patient/PatientConsultation.ts b/cypress/pageobject/Patient/PatientConsultation.ts
index 9c588f50c4e..26d75feba2e 100644
--- a/cypress/pageobject/Patient/PatientConsultation.ts
+++ b/cypress/pageobject/Patient/PatientConsultation.ts
@@ -213,7 +213,8 @@ export class PatientConsultationPage {
}
clickDischargePatient() {
- cy.get("#discharge_patient_from_care").click();
+ cy.get("#show-more").click();
+ cy.contains("p", "Discharge from CARE").click();
}
selectDischargeReason(reason: string) {
diff --git a/src/Common/constants.tsx b/src/Common/constants.tsx
index 065e7ccd759..069a39e1539 100644
--- a/src/Common/constants.tsx
+++ b/src/Common/constants.tsx
@@ -213,10 +213,10 @@ export const getBedTypes = ({
: [];
return [
- { id: 1, text: "Non-Covid Ordinary Beds" },
- { id: 150, text: "Non-Covid Oxygen beds" },
- { id: 10, text: "Non-Covid ICU (ICU without ventilator)" },
- { id: 20, text: "Non-Covid Ventilator (ICU with ventilator)" },
+ { id: 1, text: "Ordinary Beds" },
+ { id: 150, text: "Oxygen beds" },
+ { id: 10, text: "ICU (ICU without ventilator)" },
+ { id: 20, text: "Ventilator (ICU with ventilator)" },
{ id: 30, text: "Covid Ordinary Beds" },
{ id: 120, text: "Covid Oxygen beds" },
{ id: 110, text: "Covid ICU (ICU without ventilator)" },
diff --git a/src/Common/utils.tsx b/src/Common/utils.tsx
index 270e2f5efe6..3596469a6d5 100644
--- a/src/Common/utils.tsx
+++ b/src/Common/utils.tsx
@@ -44,16 +44,6 @@ export const parseOptionId: (
return textArray.join(", ");
};
-export const getDimensionOrDash = (
- value: number | string | null | undefined,
- unit: string
-) => {
- if (value === undefined || value === null || value === 0 || value === "0") {
- return "-";
- }
- return value + unit;
-};
-
export const deepEqual = (x: any, y: any): boolean => {
if (x === y) return true;
diff --git a/src/Components/ABDM/ConfigureHealthFacility.tsx b/src/Components/ABDM/ConfigureHealthFacility.tsx
index a84e4b6d4b9..bccf58e47c2 100644
--- a/src/Components/ABDM/ConfigureHealthFacility.tsx
+++ b/src/Components/ABDM/ConfigureHealthFacility.tsx
@@ -178,7 +178,7 @@ export const ConfigureHealthFacility = (props: any) => {
>
{state.form.health_facility?.registered ? (
<>
-
+
The ABDM health facility is successfully linked with
care{" "}
@@ -192,7 +192,7 @@ export const ConfigureHealthFacility = (props: any) => {
>
) : (
<>
-
+
The ABDM health facility is successfully linked with
care{" "}
diff --git a/src/Components/Assets/AssetTypes.tsx b/src/Components/Assets/AssetTypes.tsx
index 8b96b6beeb7..a4005404da1 100644
--- a/src/Components/Assets/AssetTypes.tsx
+++ b/src/Components/Assets/AssetTypes.tsx
@@ -8,6 +8,7 @@ export interface AssetLocationObject {
description: string;
created_date?: string;
modified_date?: string;
+ middleware_address?: string;
facility: {
id: string;
name: string;
diff --git a/src/Components/Common/LocationSelect.tsx b/src/Components/Common/LocationSelect.tsx
index ef7280f1907..d20c843fad8 100644
--- a/src/Components/Common/LocationSelect.tsx
+++ b/src/Components/Common/LocationSelect.tsx
@@ -7,7 +7,7 @@ interface LocationSelectProps {
name: string;
disabled?: boolean;
margin?: string;
- errors: string;
+ errors?: string;
className?: string;
searchAll?: boolean;
multiple?: boolean;
diff --git a/src/Components/ExternalResult/ResultList.tsx b/src/Components/ExternalResult/ResultList.tsx
index d148b26e3f5..9aa365c7303 100644
--- a/src/Components/ExternalResult/ResultList.tsx
+++ b/src/Components/ExternalResult/ResultList.tsx
@@ -264,11 +264,11 @@ export default function ResultList() {
value={qParams.name}
placeholder="Search by name"
/>
- Search by number
setPhoneNum(e.value)}
error={phoneNumberError}
diff --git a/src/Components/Facility/AddInventoryForm.tsx b/src/Components/Facility/AddInventoryForm.tsx
index df217cad3ec..9e4f761b550 100644
--- a/src/Components/Facility/AddInventoryForm.tsx
+++ b/src/Components/Facility/AddInventoryForm.tsx
@@ -146,7 +146,7 @@ export const AddInventoryForm = (props: any) => {
if (unitName === "Dozen") {
return Number(unitData.quantity) * 12;
}
- if (unitName === "Gram") {
+ if (unitName === "gram") {
return Number(unitData.quantity) / 1000;
}
return Number(unitData.quantity);
@@ -238,6 +238,11 @@ export const AddInventoryForm = (props: any) => {
};
// if user has selected "Add stock" or "stockValidation" function is true
if (data.is_incoming || stockValidation(data)) {
+ // if user has selected grams as unit then convert it to kg
+ if (data.unit === 5) {
+ data.quantity = data.quantity / 1000;
+ data.unit = 6;
+ }
const res = await dispatchAction(postInventory(data, { facilityId }));
setIsLoading(false);
diff --git a/src/Components/Facility/ConsultationDetails/ConsultationUpdatesTab.tsx b/src/Components/Facility/ConsultationDetails/ConsultationUpdatesTab.tsx
index 736a7c81575..bb584ae93e6 100644
--- a/src/Components/Facility/ConsultationDetails/ConsultationUpdatesTab.tsx
+++ b/src/Components/Facility/ConsultationDetails/ConsultationUpdatesTab.tsx
@@ -60,7 +60,10 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => {
setMonitorBedData(monitorBedData);
const assetDataForMonitor = monitorBedData?.asset_object;
const hl7Meta = assetDataForMonitor?.meta;
- const hl7Middleware = hl7Meta?.middleware_hostname || middleware_address;
+ const hl7Middleware =
+ hl7Meta?.middleware_hostname ||
+ assetDataForMonitor?.location_object?.middleware_address ||
+ middleware_address;
if (hl7Middleware && hl7Meta?.local_ip_address) {
setHL7SocketUrl(
`wss://${hl7Middleware}/observations/${hl7Meta.local_ip_address}`
@@ -85,7 +88,9 @@ export const ConsultationUpdatesTab = (props: ConsultationTabProps) => {
setVentilatorBedData(ventilatorBedData);
const ventilatorMeta = ventilatorBedData?.asset_object?.meta;
const ventilatorMiddleware =
- ventilatorMeta?.middleware_hostname || middleware_address;
+ ventilatorMeta?.middleware_hostname ||
+ consultationBedVentilator?.location_object.middleware_address ||
+ middleware_address;
if (ventilatorMiddleware && ventilatorMeta?.local_ip_address) {
setVentilatorSocketUrl(
`wss://${ventilatorMiddleware}/observations/${ventilatorMeta?.local_ip_address}`
diff --git a/src/Components/Facility/ConsultationDetails/index.tsx b/src/Components/Facility/ConsultationDetails/index.tsx
index 7e7664707eb..2f6ca03ef06 100644
--- a/src/Components/Facility/ConsultationDetails/index.tsx
+++ b/src/Components/Facility/ConsultationDetails/index.tsx
@@ -13,10 +13,6 @@ import {
} from "../../../Redux/actions";
import { statusType, useAbortableEffect } from "../../../Common/utils";
import { lazy, useCallback, useState } from "react";
-import ButtonV2 from "../../Common/components/ButtonV2";
-import CareIcon from "../../../CAREUI/icons/CareIcon";
-import DischargeModal from "../DischargeModal";
-import DischargeSummaryModal from "../DischargeSummaryModal";
import DoctorVideoSlideover from "../DoctorVideoSlideover";
import { make as Link } from "../../Common/components/Link.bs";
import PatientInfoCard from "../../Patient/PatientInfoCard";
@@ -25,7 +21,6 @@ import { formatDateTime, relativeTime } from "../../../Utils/utils";
import { navigate, useQueryParams } from "raviger";
import { useDispatch } from "react-redux";
-import { useTranslation } from "react-i18next";
import { triggerGoal } from "../../../Integrations/Plausible";
import useAuthUser from "../../../Common/hooks/useAuthUser";
import { ConsultationUpdatesTab } from "./ConsultationUpdatesTab";
@@ -73,7 +68,6 @@ const TABS = {
};
export const ConsultationDetails = (props: any) => {
- const { t } = useTranslation();
const { facilityId, patientId, consultationId } = props;
const tab = props.tab.toUpperCase() as keyof typeof TABS;
const dispatch: any = useDispatch();
@@ -86,9 +80,6 @@ export const ConsultationDetails = (props: any) => {
);
const [patientData, setPatientData] = useState({});
const [activeShiftingData, setActiveShiftingData] = useState>([]);
- const [openDischargeSummaryDialog, setOpenDischargeSummaryDialog] =
- useState(false);
- const [openDischargeDialog, setOpenDischargeDialog] = useState(false);
const [isCameraAttached, setIsCameraAttached] = useState(false);
const getPatientGender = (patientData: any) =>
@@ -197,19 +188,6 @@ export const ConsultationDetails = (props: any) => {
const SelectedTab = TABS[tab];
- const hasActiveShiftingRequest = () => {
- if (activeShiftingData.length > 0) {
- return [
- "PENDING",
- "APPROVED",
- "DESTINATION APPROVED",
- "PATIENT TO BE PICKED UP",
- ].includes(activeShiftingData[activeShiftingData.length - 1].status);
- }
-
- return false;
- };
-
if (isLoading) {
return ;
}
@@ -272,18 +250,6 @@ export const ConsultationDetails = (props: any) => {
return (
-
setOpenDischargeSummaryDialog(false)}
- />
-
- setOpenDischargeDialog(false)}
- consultationData={consultationData}
- />
-
-
- setOpenDischargeSummaryDialog(true)}>
-
- {t("discharge_summary")}
-
-
- setOpenDischargeDialog(true)}
- disabled={!!consultationData.discharge_date}
- >
-
- {t("discharge_from_care")}
-
-
diff --git a/src/Components/Facility/ConsultationForm.tsx b/src/Components/Facility/ConsultationForm.tsx
index 486adfa5170..1d4abbedc39 100644
--- a/src/Components/Facility/ConsultationForm.tsx
+++ b/src/Components/Facility/ConsultationForm.tsx
@@ -491,6 +491,10 @@ export const ConsultationForm = (props: any) => {
errors[field] = "Field is required";
invalidForm = true;
}
+ if (dayjs(state.form.admission_date).isBefore(dayjs("2000-01-01"))) {
+ errors[field] = "Admission date cannot be before 01/01/2000";
+ invalidForm = true;
+ }
return;
case "cause_of_death":
if (state.form.suggestion === "DD" && !state.form[field]) {
diff --git a/src/Components/Facility/Consultations/Feed.tsx b/src/Components/Facility/Consultations/Feed.tsx
index 0389fe298dc..43d5b89cb38 100644
--- a/src/Components/Facility/Consultations/Feed.tsx
+++ b/src/Components/Facility/Consultations/Feed.tsx
@@ -55,15 +55,15 @@ export const Feed: React.FC
= ({ consultationId, facilityId }) => {
const [isFullscreen, setFullscreen] = useFullscreen();
const [videoStartTime, setVideoStartTime] = useState(null);
const [statusReported, setStatusReported] = useState(false);
+ const [facilityMiddlewareHostname, setFacilityMiddlewareHostname] =
+ useState("");
const authUser = useAuthUser();
- let facilityMiddlewareHostname = "";
-
useQuery(routes.getPermittedFacility, {
pathParams: { id: facilityId || "" },
onResponse: ({ res, data }) => {
if (res && res.status === 200 && data && data.middleware_address) {
- facilityMiddlewareHostname = data.middleware_address;
+ setFacilityMiddlewareHostname(data.middleware_address);
}
},
});
diff --git a/src/Components/Facility/DischargeModal.tsx b/src/Components/Facility/DischargeModal.tsx
index 138e74fb9b9..3384efa686b 100644
--- a/src/Components/Facility/DischargeModal.tsx
+++ b/src/Components/Facility/DischargeModal.tsx
@@ -8,9 +8,7 @@ import ClaimDetailCard from "../HCX/ClaimDetailCard";
import { ConsultationModel } from "./models";
import CreateClaimCard from "../HCX/CreateClaimCard";
import { DISCHARGE_REASONS } from "../../Common/constants";
-import DateFormField from "../Form/FormFields/DateFormField";
import DialogModal from "../Common/Dialog";
-import { FieldChangeEvent } from "../Form/FormFields/Utils";
import { FieldLabel } from "../Form/FormFields/FormField";
import { HCXActions } from "../../Redux/actions";
import { HCXClaimModel } from "../HCX/models";
@@ -161,11 +159,6 @@ const DischargeModal = ({
setIsSendingDischargeApi(false);
if (dischargeResponse?.status === 200) {
- // TODO: check this later
- // const dischargeData = Object.assign({}, patientData);
- // dischargeData["discharge"] = value;
- // setPatientData(dischargeData);
-
Notification.Success({
msg: "Patient Discharged Successfully",
});
@@ -174,15 +167,6 @@ const DischargeModal = ({
}
};
- const handleDateChange = (e: FieldChangeEvent) => {
- setPreDischargeForm((form) => {
- return {
- ...form,
- discharge_date: e.value.toString(),
- };
- });
- };
-
const handleFacilitySelect = (selected: FacilityModel) => {
setFacility(selected);
const { id, name } = selected || {};
@@ -248,11 +232,10 @@ const DischargeModal = ({
- {preDischargeForm.discharge_reason === "REC" && (
-
-
+
{
+ const updates: Record = {
+ discharge_date: undefined,
+ death_datetime: undefined,
+ };
+ updates[e.name] = e.value;
+ setPreDischargeForm((form) => ({ ...form, ...updates }));
+ }}
+ required
+ min={dayjs(
+ consultationData?.admission_date ?? consultationData?.created_date
+ ).format("YYYY-MM-DDTHH:mm")}
+ max={dayjs().format("YYYY-MM-DDTHH:mm")}
+ error={
+ preDischargeForm.discharge_reason === "EXP"
+ ? errors?.death_datetime
+ : errors?.discharge_date
+ }
+ />
+ {preDischargeForm.discharge_reason === "REC" && (
+ <>
Discharge Prescription Medications
@@ -288,61 +296,24 @@ const DischargeModal = ({
Discharge PRN Prescriptions
-
+ >
)}
{preDischargeForm.discharge_reason === "EXP" && (
-
- {
- setPreDischargeForm((form) => {
- return {
- ...form,
- death_datetime: e.value,
- };
- });
- }}
- required
- min={dayjs(consultationData?.admission_date).format(
- "YYYY-MM-DDTHH:mm"
- )}
- max={dayjs().format("YYYY-MM-DDTHH:mm")}
- />
- {
- setPreDischargeForm((form) => {
- return {
- ...form,
- death_confirmed_doctor: e.value,
- };
- });
- }}
- required
- placeholder="Attending Doctor's Name and Designation"
- />
-
- )}
- {["REF", "LAMA"].includes(preDischargeForm.discharge_reason) && (
-
-
-
+ {
+ setPreDischargeForm((form) => {
+ return {
+ ...form,
+ death_confirmed_doctor: e.value,
+ };
+ });
+ }}
+ required
+ placeholder="Attending Doctor's Name and Designation"
+ />
)}
diff --git a/src/Components/Facility/FacilityBedCapacity.tsx b/src/Components/Facility/FacilityBedCapacity.tsx
new file mode 100644
index 00000000000..0c05fb022cb
--- /dev/null
+++ b/src/Components/Facility/FacilityBedCapacity.tsx
@@ -0,0 +1,119 @@
+import { useState } from "react";
+import { getBedTypes } from "../../Common/constants";
+import routes from "../../Redux/api";
+import { NonReadOnlyUsers } from "../../Utils/AuthorizeFor";
+import useQuery from "../../Utils/request/useQuery";
+import DialogModal from "../Common/Dialog";
+import ButtonV2 from "../Common/components/ButtonV2";
+import { BedCapacity } from "./BedCapacity";
+import BedTypeCard from "./BedTypeCard";
+import useConfig from "../../Common/hooks/useConfig";
+
+export const FacilityBedCapacity = (props: any) => {
+ const [bedCapacityModalOpen, setBedCapacityModalOpen] = useState(false);
+ const config = useConfig();
+
+ const capacityQuery = useQuery(routes.getCapacity, {
+ pathParams: { facilityId: props.facilityId },
+ });
+
+ let capacityList: any = null;
+ if (!capacityQuery.data || !capacityQuery.data.results.length) {
+ capacityList = (
+
+ No Bed Types Found
+
+ );
+ } else {
+ const totalBedCount = capacityQuery.data.results.reduce(
+ (acc, x) => acc + (x.total_capacity ? x.total_capacity : 0),
+ 0
+ );
+ const totalOccupiedBedCount = capacityQuery.data.results.reduce(
+ (acc, x) => acc + (x.current_capacity ? x.current_capacity : 0),
+ 0
+ );
+
+ capacityList = (
+
+ {
+ return;
+ }}
+ />
+ {getBedTypes(config).map((x) => {
+ const res = capacityQuery.data?.results.find((data) => {
+ return data.room_type === x.id;
+ });
+ if (
+ res &&
+ res.current_capacity !== undefined &&
+ res.total_capacity !== undefined
+ ) {
+ const removeCurrentBedType = (bedTypeId: number | undefined) => {
+ if (capacityQuery.data !== undefined) {
+ capacityQuery.data.results.filter((i) => i.id !== bedTypeId);
+ capacityQuery.refetch();
+ }
+ };
+ return (
+ {
+ capacityQuery.refetch();
+ }}
+ />
+ );
+ }
+ })}
+
+ );
+ }
+
+ return (
+
+
+
+
Bed Capacity
+
setBedCapacityModalOpen(true)}
+ authorizeFor={NonReadOnlyUsers}
+ >
+
+ Add More Bed Types
+
+
+
{capacityList}
+
+
+ {bedCapacityModalOpen && (
+ setBedCapacityModalOpen(false)}
+ title="Add Bed Capacity"
+ className="max-w-md md:min-w-[600px]"
+ >
+ setBedCapacityModalOpen(false)}
+ handleUpdate={async () => {
+ capacityQuery.refetch();
+ }}
+ />
+
+ )}
+
+ );
+};
diff --git a/src/Components/Facility/FacilityCard.tsx b/src/Components/Facility/FacilityCard.tsx
index e8e0dbef70f..900b6b00f47 100644
--- a/src/Components/Facility/FacilityCard.tsx
+++ b/src/Components/Facility/FacilityCard.tsx
@@ -1,9 +1,6 @@
import { useState } from "react";
-import { useDispatch } from "react-redux";
import { Link } from "raviger";
import { useTranslation } from "react-i18next";
-
-import { sendNotificationMessages } from "../../Redux/actions";
import { FACILITY_FEATURE_TYPES } from "../../Common/constants";
import ButtonV2, { Cancel, Submit } from "../Common/components/ButtonV2";
import * as Notification from "../../Utils/Notifications.js";
@@ -14,26 +11,28 @@ import DialogModal from "../Common/Dialog";
import TextAreaFormField from "../Form/FormFields/TextAreaFormField";
import useConfig from "../../Common/hooks/useConfig";
import { classNames } from "../../Utils/utils";
+import request from "../../Utils/request/request";
+import routes from "../../Redux/api";
export const FacilityCard = (props: { facility: any; userType: any }) => {
const { facility, userType } = props;
const { kasp_string } = useConfig();
const { t } = useTranslation();
- const dispatchAction: any = useDispatch();
const [notifyModalFor, setNotifyModalFor] = useState(undefined);
const [notifyMessage, setNotifyMessage] = useState("");
const [notifyError, setNotifyError] = useState("");
const handleNotifySubmit = async (id: any) => {
- const data = {
- facility: id,
- message: notifyMessage,
- };
- if (data.message.trim().length >= 1) {
+ if (notifyMessage.trim().length >= 1) {
setNotifyError("");
- const res = await dispatchAction(sendNotificationMessages(data));
- if (res && res.status == 204) {
+ const { res } = await request(routes.sendNotificationMessages, {
+ body: {
+ facility: id,
+ message: notifyMessage,
+ },
+ });
+ if (res?.ok) {
Notification.Success({
msg: "Facility Notified",
});
diff --git a/src/Components/Facility/FacilityCreate.tsx b/src/Components/Facility/FacilityCreate.tsx
index e742caefb82..8a7887ebc25 100644
--- a/src/Components/Facility/FacilityCreate.tsx
+++ b/src/Components/Facility/FacilityCreate.tsx
@@ -570,7 +570,10 @@ export const FacilityCreate = (props: FacilityProps) => {
});
capacityList = (
-
+
{
- {doctorList}
+
+ {doctorList}
+
);
diff --git a/src/Components/Facility/FacilityDoctorList.tsx b/src/Components/Facility/FacilityDoctorList.tsx
new file mode 100644
index 00000000000..d9a8b0d1a37
--- /dev/null
+++ b/src/Components/Facility/FacilityDoctorList.tsx
@@ -0,0 +1,121 @@
+import { useState } from "react";
+import { DOCTOR_SPECIALIZATION } from "../../Common/constants";
+import { NonReadOnlyUsers } from "../../Utils/AuthorizeFor";
+import ButtonV2 from "../Common/components/ButtonV2";
+import DialogModal from "../Common/Dialog";
+import { DoctorCapacity } from "./DoctorCapacity";
+import useQuery from "../../Utils/request/useQuery";
+import routes from "../../Redux/api";
+import { DoctorModal } from "./models";
+import DoctorsCountCard from "./DoctorsCountCard";
+import { DoctorIcon } from "../TeleIcu/Icons/DoctorIcon";
+
+export const FacilityDoctorList = (props: any) => {
+ const [doctorCapacityModalOpen, setDoctorCapacityModalOpen] = useState(false);
+ const [totalDoctors, setTotalDoctors] = useState(0);
+
+ const doctorQuery = useQuery(routes.listDoctor, {
+ pathParams: { facilityId: props.facilityId },
+ onResponse: ({ res, data }) => {
+ if (res?.ok && data) {
+ let totalCount = 0;
+ data.results.map((doctor: DoctorModal) => {
+ if (doctor.count) {
+ totalCount += doctor.count;
+ }
+ });
+ setTotalDoctors(totalCount);
+ }
+ },
+ });
+
+ let doctorList: any = null;
+ if (!doctorQuery.data || !doctorQuery.data.results.length) {
+ doctorList = (
+
+ No Doctors Found
+
+ );
+ } else {
+ doctorList = (
+
+ {/* Total Doctors Count Card */}
+
+
+
+
+
+
+
+
+ Total Doctors
+
+
{totalDoctors}
+
+
+
+
+
+ {doctorQuery.data.results.map((data: DoctorModal) => {
+ const removeCurrentDoctorData = (doctorId: number | undefined) => {
+ if (doctorQuery.data !== undefined) {
+ doctorQuery.data?.results.filter(
+ (i: DoctorModal) => i.id !== doctorId
+ );
+ doctorQuery.refetch();
+ }
+ };
+
+ return (
+
{
+ doctorQuery.refetch();
+ }}
+ {...data}
+ removeDoctor={removeCurrentDoctorData}
+ />
+ );
+ })}
+
+ );
+ }
+
+ return (
+
+
+
+
Doctors List
+
setDoctorCapacityModalOpen(true)}
+ disabled={doctorList.length === DOCTOR_SPECIALIZATION.length}
+ authorizeFor={NonReadOnlyUsers}
+ >
+
+ Add Doctor Types
+
+
+
{doctorList}
+
+
+ {doctorCapacityModalOpen && (
+ setDoctorCapacityModalOpen(false)}
+ title="Add Doctor Capacity"
+ className="max-w-md md:min-w-[600px]"
+ >
+ setDoctorCapacityModalOpen(false)}
+ handleUpdate={async () => {
+ doctorQuery.refetch();
+ }}
+ />
+
+ )}
+
+ );
+};
diff --git a/src/Components/Facility/FacilityFilter/index.tsx b/src/Components/Facility/FacilityFilter/index.tsx
index ff4d3f89508..fd6edd664d1 100644
--- a/src/Components/Facility/FacilityFilter/index.tsx
+++ b/src/Components/Facility/FacilityFilter/index.tsx
@@ -1,7 +1,6 @@
import { navigate } from "raviger";
import { FACILITY_TYPES } from "../../../Common/constants";
import useMergeState from "../../../Common/hooks/useMergeState";
-import useConfig from "../../../Common/hooks/useConfig";
import FiltersSlideover from "../../../CAREUI/interactive/FiltersSlideover";
import { useTranslation } from "react-i18next";
import StateAutocompleteFormField from "../../Common/StateAutocompleteFormField";
@@ -15,19 +14,17 @@ const clearFilterState = {
district: "",
local_body: "",
facility_type: "",
- kasp_empanelled: "",
};
function FacilityFilter(props: any) {
const { t } = useTranslation();
const { filter, onChange, closeFilter } = props;
- const { kasp_string } = useConfig();
+
const [filterState, setFilterState] = useMergeState({
state: filter.state || "",
district: filter.district || "",
local_body: filter.local_body || "",
facility_type: filter.facility_type || "",
- kasp_empanelled: filter.kasp_empanelled || "",
});
const applyFilter = () => {
@@ -36,7 +33,6 @@ function FacilityFilter(props: any) {
district: Number(filterState.district) || "",
local_body: Number(filterState.local_body) || "",
facility_type: filterState.facility_type || "",
- kasp_empanelled: filterState.kasp_empanelled || "",
};
onChange(data);
};
@@ -92,17 +88,6 @@ function FacilityFilter(props: any) {
optionValue={(option) => option.id}
placeholder={t("show_all")}
/>
-
option.text}
- optionValue={(option) => option.id}
- placeholder={t("show_all")}
- />
);
diff --git a/src/Components/Facility/FacilityHome.tsx b/src/Components/Facility/FacilityHome.tsx
index f14057d4a91..3ad295a3df3 100644
--- a/src/Components/Facility/FacilityHome.tsx
+++ b/src/Components/Facility/FacilityHome.tsx
@@ -1,50 +1,32 @@
import * as Notification from "../../Utils/Notifications.js";
import AuthorizeFor, { NonReadOnlyUsers } from "../../Utils/AuthorizeFor";
-import {
- CapacityModal,
- DoctorModal,
- FacilityModel,
- PatientStatsModel,
-} from "./models";
-import {
- DOCTOR_SPECIALIZATION,
- FACILITY_FEATURE_TYPES,
- USER_TYPES,
- getBedTypes,
-} from "../../Common/constants";
+import { FacilityModel } from "./models";
+import { FACILITY_FEATURE_TYPES, USER_TYPES } from "../../Common/constants";
import DropdownMenu, { DropdownItem } from "../Common/components/Menu";
-import {
- deleteFacility,
- getPermittedFacility,
- getTriageInfo,
- listCapacity,
- listDoctor,
-} from "../../Redux/actions";
-import { statusType, useAbortableEffect } from "../../Common/utils";
-import { lazy, useCallback, useState } from "react";
-import { useDispatch } from "react-redux";
-import { BedCapacity } from "./BedCapacity";
-import BedTypeCard from "./BedTypeCard";
+import { lazy, useState } from "react";
+
import ButtonV2 from "../Common/components/ButtonV2";
import CareIcon from "../../CAREUI/icons/CareIcon";
import Chip from "../../CAREUI/display/Chip";
import ConfirmDialog from "../Common/ConfirmDialog";
import ContactLink from "../Common/components/ContactLink";
import CoverImageEditModal from "./CoverImageEditModal";
-import DialogModal from "../Common/Dialog";
-import { DoctorCapacity } from "./DoctorCapacity";
-import { DoctorIcon } from "../TeleIcu/Icons/DoctorIcon";
-import DoctorsCountCard from "./DoctorsCountCard";
+
import Page from "../Common/components/Page";
import RecordMeta from "../../CAREUI/display/RecordMeta";
import Table from "../Common/components/Table";
import { navigate } from "raviger";
-import useConfig from "../../Common/hooks/useConfig";
import { useMessageListener } from "../../Common/hooks/useMessageListener";
import { useTranslation } from "react-i18next";
import useAuthUser from "../../Common/hooks/useAuthUser.js";
+import request from "../../Utils/request/request.js";
+import routes from "../../Redux/api.js";
+import useQuery from "../../Utils/request/useQuery.js";
+import { FacilityHomeTriage } from "./FacilityHomeTriage.js";
+import { FacilityDoctorList } from "./FacilityDoctorList.js";
+import { FacilityBedCapacity } from "./FacilityBedCapacity.js";
const Loading = lazy(() => import("../Common/Loading"));
@@ -61,80 +43,25 @@ export const getFacilityFeatureIcon = (featureId: number) => {
export const FacilityHome = (props: any) => {
const { t } = useTranslation();
const { facilityId } = props;
- const dispatch: any = useDispatch();
- const [facilityData, setFacilityData] = useState
({});
- const [capacityData, setCapacityData] = useState>([]);
- const [doctorData, setDoctorData] = useState>([]);
- const [isLoading, setIsLoading] = useState(false);
const [openDeleteDialog, setOpenDeleteDialog] = useState(false);
const [editCoverImage, setEditCoverImage] = useState(false);
const [imageKey, setImageKey] = useState(Date.now());
- const [totalDoctors, setTotalDoctors] = useState(0);
- const [patientStatsData, setPatientStatsData] = useState<
- Array
- >([]);
- const [bedCapacityModalOpen, setBedCapacityModalOpen] = useState(false);
- const [doctorCapacityModalOpen, setDoctorCapacityModalOpen] = useState(false);
const authUser = useAuthUser();
- const config = useConfig();
useMessageListener((data) => console.log(data));
- const fetchData = useCallback(
- async (status: statusType) => {
- setIsLoading(true);
- const facilityRes = await dispatch(getPermittedFacility(facilityId));
- if (facilityRes) {
- const [capacityRes, doctorRes, triageRes] = await Promise.all([
- dispatch(listCapacity({}, { facilityId })),
- dispatch(listDoctor({}, { facilityId })),
- dispatch(getTriageInfo({ facilityId })),
- ]);
- if (!status.aborted) {
- setIsLoading(false);
- if (!facilityRes.data) {
- Notification.Error({
- msg: "Something went wrong..!",
- });
- } else {
- setFacilityData(facilityRes.data);
- if (capacityRes && capacityRes.data) {
- setCapacityData(capacityRes.data.results);
- }
- if (doctorRes && doctorRes.data) {
- setDoctorData(doctorRes.data.results);
- // calculating total doctors count
- let totalCount = 0;
- doctorRes.data.results.map((doctor: DoctorModal) => {
- if (doctor.count) {
- totalCount += doctor.count;
- }
- });
- setTotalDoctors(totalCount);
- }
- if (
- triageRes &&
- triageRes.data &&
- triageRes.data.results &&
- triageRes.data.results.length
- ) {
- setPatientStatsData(triageRes.data.results);
- }
- }
+ const { data: facilityData, loading: isLoading } = useQuery(
+ routes.getPermittedFacility,
+ {
+ pathParams: {
+ id: facilityId,
+ },
+ onResponse: ({ res }) => {
+ if (!res?.ok) {
+ navigate("/not-found");
}
- } else {
- navigate("/not-found");
- setIsLoading(false);
- }
- },
- [dispatch, facilityId]
- );
-
- useAbortableEffect(
- (status: statusType) => {
- fetchData(status);
- },
- [dispatch, fetchData]
+ },
+ }
);
const handleDeleteClose = () => {
@@ -142,179 +69,24 @@ export const FacilityHome = (props: any) => {
};
const handleDeleteSubmit = async () => {
- const res = await dispatch(deleteFacility(facilityId));
- if (res?.status === 204) {
- Notification.Success({
- msg: "Facility deleted successfully",
- });
- } else {
- Notification.Error({
- msg: "Error while deleting Facility: " + (res?.data?.detail || ""),
- });
- }
- navigate("/facility");
+ await request(routes.deleteFacility, {
+ pathParams: { id: facilityId },
+ onResponse: ({ res }) => {
+ if (res?.ok) {
+ Notification.Success({
+ msg: "Facility deleted successfully",
+ });
+ }
+ navigate("/facility");
+ },
+ });
};
if (isLoading) {
return ;
}
- let capacityList: any = null;
- let totalBedCount = 0;
- let totalOccupiedBedCount = 0;
- if (!capacityData || !capacityData.length) {
- capacityList = (
-
- No Bed Types Found
-
- );
- } else {
- capacityData.forEach((x) => {
- totalBedCount += x.total_capacity ? x.total_capacity : 0;
- totalOccupiedBedCount += x.current_capacity ? x.current_capacity : 0;
- });
-
- capacityList = (
-
- {
- return;
- }}
- />
- {getBedTypes(config).map((x) => {
- const res = capacityData.find((data) => {
- return data.room_type === x.id;
- });
- if (
- res &&
- res.current_capacity !== undefined &&
- res.total_capacity !== undefined
- ) {
- const removeCurrentBedType = (bedTypeId: number | undefined) => {
- setCapacityData((state) =>
- state.filter((i) => i.id !== bedTypeId)
- );
- };
- return (
- {
- const capacityRes = await dispatch(
- listCapacity({}, { facilityId })
- );
- if (capacityRes && capacityRes.data) {
- setCapacityData(capacityRes.data.results);
- }
- }}
- />
- );
- }
- })}
-
- );
- }
- let doctorList: any = null;
- if (!doctorData || !doctorData.length) {
- doctorList = (
-
- No Doctors Found
-
- );
- } else {
- doctorList = (
-
- {/* Total Doctors Count Card */}
-
-
-
-
-
-
-
-
- Total Doctors
-
-
{totalDoctors}
-
-
-
-
-
- {doctorData.map((data: DoctorModal) => {
- const removeCurrentDoctorData = (doctorId: number | undefined) => {
- setDoctorData((state) =>
- state.filter((i: DoctorModal) => i.id !== doctorId)
- );
- };
-
- return (
-
{
- const doctorRes = await dispatch(
- listDoctor({}, { facilityId })
- );
- if (doctorRes && doctorRes.data) {
- setDoctorData(doctorRes.data.results);
- // update total doctors count
- let totalCount = 0;
- doctorRes.data.results.map((doctor: DoctorModal) => {
- if (doctor.count) {
- totalCount += doctor.count;
- }
- });
- setTotalDoctors(totalCount);
- }
- }}
- {...data}
- removeDoctor={removeCurrentDoctorData}
- />
- );
- })}
-
- );
- }
-
- const stats: (string | JSX.Element)[][] = [];
- for (let i = 0; i < patientStatsData.length; i++) {
- const temp: (string | JSX.Element)[] = [];
- temp.push(String(patientStatsData[i].entry_date) || "0");
- temp.push(String(patientStatsData[i].num_patients_visited) || "0");
- temp.push(String(patientStatsData[i].num_patients_home_quarantine) || "0");
- temp.push(String(patientStatsData[i].num_patients_isolation) || "0");
- temp.push(String(patientStatsData[i].num_patient_referred) || "0");
- temp.push(
- String(patientStatsData[i].num_patient_confirmed_positive) || "0"
- );
- temp.push(
-
- navigate(`/facility/${facilityId}/triage/${patientStatsData[i].id}`)
- }
- authorizeFor={NonReadOnlyUsers}
- >
- Edit
-
- );
- stats.push(temp);
- }
-
- const hasCoverImage = !!facilityData.read_cover_image_url;
+ const hasCoverImage = !!facilityData?.read_cover_image_url;
const StaffUserTypeIndex = USER_TYPES.findIndex((type) => type === "Staff");
const hasPermissionToEditCoverImage =
@@ -331,24 +103,25 @@ export const FacilityHome = (props: any) => {
const CoverImage = () => (
);
return (
- Are you sure you want to delete {facilityData.name}
+ Are you sure you want to delete{" "}
+ {facilityData?.name}
}
action="Delete"
@@ -360,13 +133,13 @@ export const FacilityHome = (props: any) => {
- facilityData.read_cover_image_url
+ facilityData?.read_cover_image_url
? setImageKey(Date.now())
: window.location.reload()
}
onClose={() => setEditCoverImage(false)}
onDelete={() => window.location.reload()}
- facility={facilityData}
+ facility={facilityData ?? ({} as FacilityModel)}
/>
{hasCoverImage ? (
{
)}
{editCoverImageTooltip}
-
-
{facilityData.name}
+
+
{facilityData?.name}
{facilityData?.modified_date && (
{
-
+
Address
- {facilityData.address}
+ {facilityData?.address}
@@ -492,13 +265,16 @@ export const FacilityHome = (props: any) => {
- {facilityData.features?.some((feature: any) =>
+ {facilityData?.features?.some((feature: any) =>
FACILITY_FEATURE_TYPES.some((f) => f.id === feature)
) && (
Available features
)}
-
- {facilityData.features?.map(
+
+ {facilityData?.features?.map(
(feature: number, i: number) =>
FACILITY_FEATURE_TYPES.some((f) => f.id === feature) && (
{
Oxygen Information
-
+
{
rows={[
[
"Capacity",
- String(facilityData.oxygen_capacity),
- String(facilityData.type_b_cylinders),
- String(facilityData.type_c_cylinders),
- String(facilityData.type_d_cylinders),
+ String(facilityData?.oxygen_capacity),
+ String(facilityData?.type_b_cylinders),
+ String(facilityData?.type_c_cylinders),
+ String(facilityData?.type_d_cylinders),
],
[
"Daily Expected Consumption",
- String(facilityData.expected_oxygen_requirement),
- String(facilityData.expected_type_b_cylinders),
- String(facilityData.expected_type_c_cylinders),
- String(facilityData.expected_type_d_cylinders),
+ String(facilityData?.expected_oxygen_requirement),
+ String(facilityData?.expected_type_b_cylinders),
+ String(facilityData?.expected_type_c_cylinders),
+ String(facilityData?.expected_type_d_cylinders),
],
]}
/>
-
-
-
Bed Capacity
-
setBedCapacityModalOpen(true)}
- authorizeFor={NonReadOnlyUsers}
- >
-
- Add More Bed Types
-
-
-
{capacityList}
-
-
-
-
Doctors List
-
setDoctorCapacityModalOpen(true)}
- disabled={doctorList.length === DOCTOR_SPECIALIZATION.length}
- authorizeFor={NonReadOnlyUsers}
- >
-
- Add Doctor Types
-
-
-
{doctorList}
-
-
-
-
-
Corona Triage
-
navigate(`/facility/${facilityId}/triage`)}
- authorizeFor={NonReadOnlyUsers}
- >
-
- Add Triage
-
-
-
-
- {stats.length === 0 && (
- <>
-
-
- No Data Found
-
- >
- )}
-
-
-
- {bedCapacityModalOpen && (
- setBedCapacityModalOpen(false)}
- title="Add Bed Capacity"
- className="max-w-md md:min-w-[600px]"
- >
- setBedCapacityModalOpen(false)}
- handleUpdate={async () => {
- const capacityRes = await dispatch(
- listCapacity({}, { facilityId })
- );
- if (capacityRes && capacityRes.data) {
- setCapacityData(capacityRes.data.results);
- }
- }}
- />
-
- )}
- {doctorCapacityModalOpen && (
- setDoctorCapacityModalOpen(false)}
- title="Add Doctor Capacity"
- className="max-w-md md:min-w-[600px]"
- >
- setDoctorCapacityModalOpen(false)}
- handleUpdate={async () => {
- const doctorRes = await dispatch(listDoctor({}, { facilityId }));
- if (doctorRes && doctorRes.data) {
- setDoctorData(doctorRes.data.results);
- // update total doctors count
- setTotalDoctors(
- doctorRes.data.results.reduce(
- (acc: number, doctor: DoctorModal) =>
- acc + (doctor.count || 0),
- 0
- )
- );
- }
- }}
- />
-
- )}
+
+
+
+
);
};
diff --git a/src/Components/Facility/FacilityHomeTriage.tsx b/src/Components/Facility/FacilityHomeTriage.tsx
new file mode 100644
index 00000000000..ba1cd199044
--- /dev/null
+++ b/src/Components/Facility/FacilityHomeTriage.tsx
@@ -0,0 +1,93 @@
+import { navigate } from "raviger";
+import ButtonV2 from "../Common/components/ButtonV2";
+import Table from "../Common/components/Table";
+import useQuery from "../../Utils/request/useQuery";
+import routes from "../../Redux/api";
+
+export const FacilityHomeTriage = (props: any) => {
+ const triageQuery = useQuery(routes.getTriage, {
+ pathParams: { facilityId: props.facilityId },
+ });
+
+ const stats: (string | JSX.Element)[][] = [];
+ for (
+ let i = 0;
+ triageQuery.data?.results && i < triageQuery.data.results.length;
+ i++
+ ) {
+ const temp: (string | JSX.Element)[] = [];
+ temp.push(String(triageQuery.data.results[i].entry_date) || "0");
+ temp.push(String(triageQuery.data.results[i].num_patients_visited) || "0");
+ temp.push(
+ String(triageQuery.data.results[i].num_patients_home_quarantine) || "0"
+ );
+ temp.push(
+ String(triageQuery.data.results[i].num_patients_isolation) || "0"
+ );
+ temp.push(String(triageQuery.data.results[i].num_patient_referred) || "0");
+ temp.push(
+ String(triageQuery.data.results[i].num_patient_confirmed_positive) || "0"
+ );
+ temp.push(
+
+ navigate(
+ `/facility/${props.facilityId}/triage/${triageQuery.data?.results[i].id}`
+ )
+ }
+ authorizeFor={props.NonReadOnlyUsers}
+ >
+ Edit
+
+ );
+ stats.push(temp);
+ }
+
+ return (
+
+
+
+
Corona Triage
+
navigate(`/facility/${props.facilityId}/triage`)}
+ authorizeFor={props.NonReadOnlyUsers}
+ >
+
+ Add Triage
+
+
+
+
+ {stats.length === 0 && (
+ <>
+
+
+ No Data Found
+
+ >
+ )}
+
+
+
+ );
+};
diff --git a/src/Components/Facility/FacilityUsers.tsx b/src/Components/Facility/FacilityUsers.tsx
index 6963c4006db..aba12cc3833 100644
--- a/src/Components/Facility/FacilityUsers.tsx
+++ b/src/Components/Facility/FacilityUsers.tsx
@@ -1,18 +1,7 @@
-import { lazy, useCallback, useEffect, useState } from "react";
-import { useDispatch } from "react-redux";
+import { lazy, useState } from "react";
import CountBlock from "../../CAREUI/display/Count";
import CareIcon from "../../CAREUI/icons/CareIcon";
import { RESULTS_PER_PAGE_LIMIT } from "../../Common/constants";
-import useAuthUser from "../../Common/hooks/useAuthUser";
-import { statusType, useAbortableEffect } from "../../Common/utils";
-import {
- addUserFacility,
- deleteUser,
- deleteUserFacility,
- getAnyFacility,
- getFacilityUsers,
- getUserListFacility,
-} from "../../Redux/actions";
import * as Notification from "../../Utils/Notifications.js";
import { classNames, isUserOnline, relativeTime } from "../../Utils/utils";
import Pagination from "../Common/Pagination";
@@ -23,25 +12,22 @@ import { FacilityModel } from "../Facility/models";
import LinkFacilityDialog from "../Users/LinkFacilityDialog";
import UnlinkFacilityDialog from "../Users/UnlinkFacilityDialog";
import UserDeleteDialog from "../Users/UserDeleteDialog";
+import useAuthUser from "../../Common/hooks/useAuthUser";
+import request from "../../Utils/request/request";
+import routes from "../../Redux/api";
+import useQuery from "../../Utils/request/useQuery";
const Loading = lazy(() => import("../Common/Loading"));
export default function FacilityUsers(props: any) {
const { facilityId } = props;
- const dispatch: any = useDispatch();
- const initialData: any[] = [];
let manageUsers: any = null;
- const [users, setUsers] = useState(initialData);
- const [isLoading, setIsLoading] = useState(false);
- const [isFacilityLoading, setIsFacilityLoading] = useState(false);
- const [totalCount, setTotalCount] = useState(0);
+ const [isUnlinkFacilityLoading, setIsUnlinkFacilityLoading] = useState(false);
+ const [isAddFacilityLoading, setIsAddFacilityLoading] = useState(false);
+ const [isLoadFacilityLoading, setIsLoadFacilityLoading] = useState(false);
const [currentPage, setCurrentPage] = useState(1);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [offset, setOffset] = useState(0);
- const [facilityData, setFacilityData] = useState({
- name: "",
- district_object_id: 0,
- });
const authUser = useAuthUser();
const [linkFacility, setLinkFacility] = useState<{
@@ -63,48 +49,22 @@ export default function FacilityUsers(props: any) {
const limit = RESULTS_PER_PAGE_LIMIT;
- useEffect(() => {
- async function fetchFacilityName() {
- if (facilityId) {
- const res = await dispatch(getAnyFacility(facilityId));
- setFacilityData({
- name: res?.data?.name || "",
- district_object_id: res?.data?.district_object?.id || 0,
- });
- } else {
- setFacilityData({
- name: "",
- district_object_id: 0,
- });
- }
- }
- fetchFacilityName();
- }, [dispatch, facilityId]);
-
- const fetchData = useCallback(
- async (status: statusType) => {
- setIsLoading(true);
- const res = await dispatch(
- getFacilityUsers(facilityId, { offset, limit })
- );
-
- if (!status.aborted) {
- if (res && res.data) {
- setUsers(res.data.results);
- setTotalCount(res.data.count);
- }
- setIsLoading(false);
- }
+ const { data: facilityData } = useQuery(routes.getAnyFacility, {
+ pathParams: {
+ id: facilityId,
},
- [dispatch, facilityId, offset, limit]
- );
+ prefetch: facilityId !== undefined,
+ });
- useAbortableEffect(
- (status: statusType) => {
- fetchData(status);
- },
- [fetchData]
- );
+ const {
+ data: facilityUserData,
+ refetch: facilityUserFetch,
+ loading: isLoading,
+ } = useQuery(routes.getFacilityUsers, {
+ query: { offset: offset, limit: limit },
+ pathParams: { facility_id: facilityId },
+ prefetch: facilityId !== undefined,
+ });
const handlePagination = (page: number, limit: number) => {
const offset = (page - 1) * limit;
@@ -113,23 +73,24 @@ export default function FacilityUsers(props: any) {
};
const loadFacilities = async (username: string) => {
- if (isFacilityLoading) {
+ if (isUnlinkFacilityLoading || isAddFacilityLoading) {
return;
}
- setIsFacilityLoading(true);
- const res = await dispatch(getUserListFacility({ username }));
- if (res && res.data) {
- const updated = users.map((user) => {
+ setIsLoadFacilityLoading(true);
+ const { res, data } = await request(routes.userListFacility, {
+ pathParams: { username: username },
+ });
+ if (res?.ok && data && facilityUserData) {
+ facilityUserData.results = facilityUserData.results.map((user) => {
return user.username === username
? {
...user,
- facilities: res.data,
+ facilities: data,
}
: user;
});
- setUsers(updated);
}
- setIsFacilityLoading(false);
+ setIsLoadFacilityLoading(false);
};
const showLinkFacilityModal = (username: string) => {
@@ -155,14 +116,22 @@ export default function FacilityUsers(props: any) {
};
const handleUnlinkFacilitySubmit = async () => {
- setIsFacilityLoading(true);
- await dispatch(
- deleteUserFacility(
- unlinkFacilityData.userName,
- String(unlinkFacilityData?.facility?.id)
- )
- );
- setIsFacilityLoading(false);
+ setIsUnlinkFacilityLoading(true);
+ await request(routes.deleteUserFacility, {
+ // body given in the dispatch call but there is no body in API documentation
+ body: { facility: String(unlinkFacilityData?.facility?.id) },
+ pathParams: {
+ username: unlinkFacilityData.userName,
+ },
+ onResponse: ({ res }) => {
+ if (res?.status === 204) {
+ Notification.Success({
+ msg: "User Facility deleted successfully",
+ });
+ }
+ },
+ });
+ setIsUnlinkFacilityLoading(false);
loadFacilities(unlinkFacilityData.userName);
hideUnlinkFacilityModal();
};
@@ -173,19 +142,18 @@ export default function FacilityUsers(props: any) {
const handleSubmit = async () => {
const username = userData.username;
- const res = await dispatch(deleteUser(username));
- if (res?.status === 204) {
- Notification.Success({
- msg: "User deleted successfully",
- });
- } else {
- Notification.Error({
- msg: "Error while deleting User: " + (res?.data?.detail || ""),
- });
- }
-
+ await request(routes.deleteUser, {
+ pathParams: { username: username },
+ onResponse: ({ res }) => {
+ if (res?.status === 204) {
+ Notification.Success({
+ msg: "User deleted successfully",
+ });
+ }
+ },
+ });
setUserData({ show: false, username: "", name: "" });
- fetchData({ aborted: false });
+ facilityUserFetch();
};
const handleDelete = (user: any) => {
@@ -198,7 +166,9 @@ export default function FacilityUsers(props: any) {
const facilityClassname = classNames(
"align-baseline text-sm font-bold",
- isFacilityLoading ? "text-gray-500" : "text-blue-500 hover:text-blue-800"
+ isAddFacilityLoading || isUnlinkFacilityLoading || isLoadFacilityLoading
+ ? "text-gray-500"
+ : "text-blue-500 hover:text-blue-800"
);
const showLinkFacility = (username: string) => {
@@ -236,7 +206,7 @@ export default function FacilityUsers(props: any) {
size="small"
circle
variant="secondary"
- disabled={isFacilityLoading}
+ disabled={isUnlinkFacilityLoading}
onClick={() =>
setUnlinkFacilityData({
show: true,
@@ -267,17 +237,26 @@ export default function FacilityUsers(props: any) {
const addFacility = async (username: string, facility: any) => {
hideLinkFacilityModal();
- setIsFacilityLoading(true);
- await dispatch(addUserFacility(username, String(facility.id)));
- setIsFacilityLoading(false);
+ setIsAddFacilityLoading(true);
+ // Remaining props of request are not specified in dispatch request
+ await request(routes.addUserFacility, {
+ body: {
+ facility: String(facility.id),
+ },
+ pathParams: {
+ username: username,
+ },
+ });
+ setIsAddFacilityLoading(false);
loadFacilities(username);
};
let userList: any[] = [];
- users &&
- users.length &&
- (userList = users.map((user: any) => {
+ facilityUserData &&
+ facilityUserData.results &&
+ facilityUserData.results.length &&
+ (userList = facilityUserData.results.map((user: any) => {
return (
;
- } else if (users && users.length) {
+ } else if (facilityUserData.results && facilityUserData.results.length) {
manageUsers = (
{userList}
- {totalCount > limit && (
+ {facilityUserData && facilityUserData.count > limit && (
)}
);
- } else if (users && users.length === 0) {
+ } else if (
+ facilityUserData.results &&
+ facilityUserData.results.length === 0
+ ) {
manageUsers = (
@@ -443,15 +425,16 @@ export default function FacilityUsers(props: any) {
)}
-
+ {facilityUserData && (
+
+ )}
-
diff --git a/src/Components/Facility/models.tsx b/src/Components/Facility/models.tsx
index 8dcc5f71e0d..cdc7074c145 100644
--- a/src/Components/Facility/models.tsx
+++ b/src/Components/Facility/models.tsx
@@ -488,3 +488,16 @@ export interface PatientNotesModel {
user_type?: string;
created_date: string;
}
+
+export type IFacilityNotificationRequest = {
+ facility: string;
+ message: string;
+};
+
+export type IFacilityNotificationResponse = {
+ [key: string]: string;
+};
+
+export type IUserFacilityRequest = {
+ facility: string;
+};
diff --git a/src/Components/Form/FormFields/FormField.tsx b/src/Components/Form/FormFields/FormField.tsx
index af5a3e91804..ffd42c0d50e 100644
--- a/src/Components/Form/FormFields/FormField.tsx
+++ b/src/Components/Form/FormFields/FormField.tsx
@@ -1,6 +1,6 @@
+import { classNames } from "../../../Utils/utils";
import { FieldError } from "../FieldValidators";
import { FormFieldBaseProps } from "./Utils";
-import { classNames } from "../../../Utils/utils";
type LabelProps = {
id?: string | undefined;
diff --git a/src/Components/Patient/DailyRounds.tsx b/src/Components/Patient/DailyRounds.tsx
index 72075939bd7..ce619370d03 100644
--- a/src/Components/Patient/DailyRounds.tsx
+++ b/src/Components/Patient/DailyRounds.tsx
@@ -501,7 +501,6 @@ export const DailyRounds = (props: any) => {
value && dayjs(value).isValid() && dayjs(value).toDate();
@@ -587,10 +587,10 @@ export default function PatientFilter(props: any) {
}
expanded={true}
- className="w-full rounded-md"
+ className="rounded-md"
>
-
-
+
+
Facility
setFacility(obj, "facility")}
/>
-
- Location
-
- setFilterState({
- ...filterState,
- last_consultation_current_bed__location: selected,
- })
- }
- />
-
-
+ {filterState.facility && (
+
+ Location
+
+ setFilterState({
+ ...filterState,
+ last_consultation_current_bed__location: selected,
+ })
+ }
+ />
+
+ )}
+
Facility type
-
+
LSG Body
-
+
District
void;
+ activeShiftingData: any;
consultationId: string;
showAbhaProfile?: boolean;
}) {
const authUser = useAuthUser();
-
+ const { t } = useTranslation();
const [open, setOpen] = useState(false);
const [showLinkABHANumber, setShowLinkABHANumber] = useState(false);
const [showABHAProfile, setShowABHAProfile] = useState(
!!props.showAbhaProfile
);
+ const [openDischargeSummaryDialog, setOpenDischargeSummaryDialog] =
+ useState(false);
+ const [openDischargeDialog, setOpenDischargeDialog] = useState(false);
const { enable_hcx, enable_abdm } = useConfig();
const [showLinkCareContext, setShowLinkCareContext] = useState(false);
const patient = props.patient;
const consultation = props.consultation;
+ const activeShiftingData = props.activeShiftingData;
const [medicoLegalCase, setMedicoLegalCase] = useState(
consultation?.medico_legal_case ?? false
@@ -86,6 +93,19 @@ export default function PatientInfoCard(props: {
}
};
+ const hasActiveShiftingRequest = () => {
+ if (activeShiftingData.length > 0) {
+ return [
+ "PENDING",
+ "APPROVED",
+ "DESTINATION APPROVED",
+ "PATIENT TO BE PICKED UP",
+ ].includes(activeShiftingData[activeShiftingData.length - 1].status);
+ }
+
+ return false;
+ };
+
return (
<>
Invalid Patient Data
)}
+
+ {consultation && (
+ <>
+
setOpenDischargeSummaryDialog(false)}
+ />
+ setOpenDischargeDialog(false)}
+ consultationData={consultation}
+ />
+ >
+ )}
+
{/* Can support for patient picture in the future */}
@@ -247,17 +283,6 @@ export default function PatientInfoCard(props: {
{[
- ["Blood Group", patient.blood_group, patient.blood_group],
- [
- "Weight",
- getDimensionOrDash(consultation?.weight, " kg"),
- true,
- ],
- [
- "Height",
- getDimensionOrDash(consultation?.height, "cm"),
- true,
- ],
[
"Respiratory Support",
RESPIRATORY_SUPPORT.find(
@@ -305,7 +330,8 @@ export default function PatientInfoCard(props: {
) : (
{" "}
- Discharged on {formatDate(consultation?.discharge_date)}
+ Discharged on{" "}
+ {formatDateTime(consultation?.discharge_date)}
)}
@@ -323,7 +349,11 @@ export default function PatientInfoCard(props: {
{!consultation?.discharge_reason ? (
- UNKNOWN
+
+ {consultation.suggestion === "OP"
+ ? "OP file closed"
+ : "UNKNOWN"}
+
) : consultation?.discharge_reason === "EXP" ? (
EXPIRED
) : (
@@ -406,6 +436,7 @@ export default function PatientInfoCard(props: {
)
)}
}
@@ -545,6 +576,94 @@ export default function PatientInfoCard(props: {
))}
+
+ {!consultation?.discharge_date && (
+
+ {({ close }) => (
+ <>
+ {hasActiveShiftingRequest() ? (
+ {
+ close();
+ navigate(
+ `/shifting/${
+ activeShiftingData[
+ activeShiftingData.length - 1
+ ].id
+ }`
+ );
+ }}
+ >
+
+
+ Track Shifting
+
+
+ ) : (
+ {
+ close();
+ navigate(
+ `/facility/${patient.facility}/patient/${patient.id}/shift/new`
+ );
+ }}
+ >
+
+
+ Shift Patient
+
+
+ )}
+ >
+ )}
+
+ )}
+
+ {({ close }) => (
+ {
+ close();
+ setOpenDischargeSummaryDialog(true);
+ }}
+ >
+
+
+ {t("discharge_summary")}
+
+
+ )}
+
+
+ {({ close }) => (
+ {
+ if (!consultation?.discharge_date) {
+ close();
+ setOpenDischargeDialog(true);
+ }
+ }}
+ >
+
+
+ {t("discharge_from_care")}
+
+
+ )}
+
+
-
-
-
-
+
+
);
}
diff --git a/src/Components/VitalsMonitor/HL7PatientVitalsMonitor.tsx b/src/Components/VitalsMonitor/HL7PatientVitalsMonitor.tsx
index 6533d133089..d91b0c56b2f 100644
--- a/src/Components/VitalsMonitor/HL7PatientVitalsMonitor.tsx
+++ b/src/Components/VitalsMonitor/HL7PatientVitalsMonitor.tsx
@@ -236,7 +236,7 @@ export const VitalsNonWaveformContent = ({
}: {
children: JSX.Element | JSX.Element[];
}) => (
-
+
{children}
);
diff --git a/src/Redux/actions.tsx b/src/Redux/actions.tsx
index a120c384a3d..e380949887b 100644
--- a/src/Redux/actions.tsx
+++ b/src/Redux/actions.tsx
@@ -56,9 +56,6 @@ export const updateFacility = (id: string, params: object) => {
export const partialUpdateFacility = (id: string, params: object) => {
return fireRequest("partialUpdateFacility", [id], params);
};
-export const deleteFacility = (id: string) => {
- return fireRequest("deleteFacility", [id], {});
-};
export const deleteFacilityCoverImage = (id: string) => {
return fireRequest("deleteFacilityCoverImage", [], {}, { id });
};
@@ -681,10 +678,6 @@ export const getPublicKey = () => {
return fireRequest("getPublicKey", [], {}, {});
};
-export const sendNotificationMessages = (params: object) => {
- return fireRequest("sendNotificationMessages", [], params, {});
-};
-
// FileUpload
export const createUpload = (params: object) => {
diff --git a/src/Redux/api.tsx b/src/Redux/api.tsx
index a69914bddb7..4172effe432 100644
--- a/src/Redux/api.tsx
+++ b/src/Redux/api.tsx
@@ -29,13 +29,19 @@ import {
AssetUpdate,
} from "../Components/Assets/AssetTypes";
import {
+ CapacityModal,
ConsultationModel,
CreateBedBody,
CurrentBed,
DailyRoundsBody,
DailyRoundsRes,
+ DoctorModal,
FacilityModel,
+ IFacilityNotificationRequest,
+ IFacilityNotificationResponse,
+ IUserFacilityRequest,
LocationModel,
+ PatientStatsModel,
WardModel,
} from "../Components/Facility/models";
import {
@@ -162,11 +168,14 @@ const routes = {
userListFacility: {
path: "/api/v1/users/{username}/get_facilities/",
+ TRes: Type
(),
},
addUserFacility: {
path: "/api/v1/users/{username}/add_facility/",
method: "PUT",
+ TBody: Type(),
+ TRes: Type(),
},
addUserSkill: {
@@ -177,6 +186,8 @@ const routes = {
deleteUserFacility: {
path: "/api/v1/users/{username}/delete_facility/",
method: "DELETE",
+ TBody: Type(),
+ TRes: Type>(),
},
clearHomeFacility: {
@@ -206,8 +217,9 @@ const routes = {
},
deleteUser: {
- path: "/api/v1/users",
+ path: "/api/v1/users/{username}/",
method: "DELETE",
+ TRes: Type>(),
},
addUser: {
@@ -288,6 +300,7 @@ const routes = {
getFacilityUsers: {
path: "/api/v1/facility/{facility_id}/get_users/",
+ TRes: Type>(),
},
listFacilityAssetLocation: {
@@ -403,8 +416,9 @@ const routes = {
// Download Api
deleteFacility: {
- path: "/api/v1/facility",
+ path: "/api/v1/facility/{id}/",
method: "DELETE",
+ TRes: Type>(),
},
downloadFacility: {
@@ -496,6 +510,7 @@ const routes = {
getCapacity: {
path: "/api/v1/facility/{facilityId}/capacity/",
+ TRes: Type>(),
},
getCapacityBed: {
@@ -509,6 +524,7 @@ const routes = {
listDoctor: {
path: "/api/v1/facility/{facilityId}/hospital_doctor/",
+ TRes: Type>(),
},
getDoctor: {
path: "/api/v1/facility/{facilityId}/hospital_doctor/{id}/",
@@ -536,6 +552,7 @@ const routes = {
},
getTriage: {
path: "/api/v1/facility/{facilityId}/patient_stats/",
+ TRes: Type>(),
},
getTriageDetails: {
@@ -841,6 +858,8 @@ const routes = {
sendNotificationMessages: {
path: "/api/v1/notification/notify/",
method: "POST",
+ TRes: Type(),
+ Tbody: Type(),
},
// FileUpload Create