From fedb2e20698731f10cf69d5750f3763b416def32 Mon Sep 17 00:00:00 2001 From: Rithvik Nishad Date: Sat, 6 Jan 2024 19:22:30 +0530 Subject: [PATCH 1/6] Fix blood pressure being negative values when field is cleared (#6986) * Fix negative values from being internally recorded in blood pressure * make validator name more verbose and readable * remove console logs --- .../Common/BloodPressureFormField.tsx | 47 ++++++++++++------- .../Facility/Consultations/Mews.tsx | 2 - .../Patient/DailyRoundListDetails.tsx | 10 +--- src/Components/Patient/DailyRounds.tsx | 44 ++++------------- src/Components/Patient/models.tsx | 10 ++-- 5 files changed, 46 insertions(+), 67 deletions(-) diff --git a/src/Components/Common/BloodPressureFormField.tsx b/src/Components/Common/BloodPressureFormField.tsx index 3ff2774b900..e64b2a15ff6 100644 --- a/src/Components/Common/BloodPressureFormField.tsx +++ b/src/Components/Common/BloodPressureFormField.tsx @@ -1,3 +1,4 @@ +import { FieldValidator } from "../Form/FieldValidators"; import FormField from "../Form/FormFields/FormField"; import RangeAutocompleteFormField from "../Form/FormFields/RangeAutocompleteFormField"; import { @@ -5,40 +6,36 @@ import { FormFieldBaseProps, useFormFieldPropsResolver, } from "../Form/FormFields/Utils"; +import { DailyRoundsModel } from "../Patient/models"; -export interface BloodPressure { - systolic: number; - diastolic: number; -} +type BloodPressure = NonNullable; -type Props = FormFieldBaseProps>; +type Props = FormFieldBaseProps; export default function BloodPressureFormField(props: Props) { const field = useFormFieldPropsResolver(props as any); const handleChange = (event: FieldChangeEvent) => { - field.onChange({ - name: field.name, - value: { - ...field.value, - [event.name]: event.value ?? -1, - }, - }); + const value: BloodPressure = { + ...field.value, + [event.name]: event.value, + }; + value.mean = meanArterialPressure(value); + field.onChange({ name: field.name, value }); }; const map = !!props.value?.diastolic && !!props.value.systolic && - meanArterialPressure(props.value as BloodPressure); + meanArterialPressure(props.value); return ( MAP: {map.toFixed(1)} - ) : undefined, + labelSuffix: map ? ( + MAP: {map.toFixed(1)} + ) : undefined, }} >
@@ -108,5 +105,19 @@ export const meanArterialPressure = ({ diastolic, systolic, }: BloodPressure) => { - return (2 * diastolic + systolic) / 3; + if (diastolic != null && systolic != null) { + return (2 * diastolic + systolic) / 3; + } +}; + +export const BloodPressureValidator: FieldValidator = (bp) => { + if (Object.values(bp).every((v) => v == null)) { + return; + } + if (bp.diastolic == null) { + return "Diastolic is missing. Either specify both or clear both."; + } + if (bp.systolic == null) { + return "Systolic is missing. Either specify both or clear both."; + } }; diff --git a/src/Components/Facility/Consultations/Mews.tsx b/src/Components/Facility/Consultations/Mews.tsx index 5160e42f9f2..14e7d7f9e63 100644 --- a/src/Components/Facility/Consultations/Mews.tsx +++ b/src/Components/Facility/Consultations/Mews.tsx @@ -26,7 +26,6 @@ const getHeartRateScore = (value?: number) => { const getSystolicBPScore = (value?: number) => { if (typeof value !== "number") return; - if (value === -1) return; if (value <= 70) return 3; if (value <= 80) return 2; @@ -38,7 +37,6 @@ const getSystolicBPScore = (value?: number) => { }; const getTempRange = (value?: number) => { - console.log(value); if (typeof value !== "number") return; if (value < 95) return 2; diff --git a/src/Components/Patient/DailyRoundListDetails.tsx b/src/Components/Patient/DailyRoundListDetails.tsx index 0a73607d688..8f313c0a51d 100644 --- a/src/Components/Patient/DailyRoundListDetails.tsx +++ b/src/Components/Patient/DailyRoundListDetails.tsx @@ -158,20 +158,14 @@ export const DailyRoundListDetails = (props: any) => { Systolic:{" "} - {dailyRoundListDetailsData.bp?.systolic && - dailyRoundListDetailsData.bp?.systolic !== -1 - ? dailyRoundListDetailsData.bp?.systolic - : "-"} + {dailyRoundListDetailsData.bp?.systolic ?? "-"}
{" "} Diastolic: - {dailyRoundListDetailsData.bp?.diastolic && - dailyRoundListDetailsData.bp?.diastolic !== -1 - ? dailyRoundListDetailsData.bp?.diastolic - : "-"} + {dailyRoundListDetailsData.bp?.diastolic ?? "-"}
diff --git a/src/Components/Patient/DailyRounds.tsx b/src/Components/Patient/DailyRounds.tsx index c12aea42bee..56e26dff022 100644 --- a/src/Components/Patient/DailyRounds.tsx +++ b/src/Components/Patient/DailyRounds.tsx @@ -23,7 +23,7 @@ import { DraftSection, useAutoSaveReducer } from "../../Utils/AutoSave"; import * as Notification from "../../Utils/Notifications"; import { formatDateTime } from "../../Utils/utils"; import BloodPressureFormField, { - meanArterialPressure, + BloodPressureValidator, } from "../Common/BloodPressureFormField"; import { SymptomsSelect } from "../Common/SymptomsSelect"; import TemperatureFormField from "../Common/TemperatureFormField"; @@ -63,9 +63,9 @@ const initForm: any = { ventilator_spo2: null, consciousness_level: "UNKNOWN", bp: { - systolic: -1, - diastolic: -1, - mean: -1, + systolic: undefined, + diastolic: undefined, + mean: undefined, }, // bed: null, }; @@ -247,18 +247,14 @@ export const DailyRounds = (props: any) => { invalidForm = true; } return; - case "bp": - if ( - (state.form.bp?.systolic && - state.form.bp?.diastolic && - state.form.bp.systolic !== -1 && - state.form.bp.diastolic === -1) || - (state.form.bp.systolic === -1 && state.form.bp.diastolic !== -1) - ) { - errors.bp = "Please enter both systolic and diastolic values"; + case "bp": { + const error = BloodPressureValidator(state.form.bp); + if (error) { + errors.bp = error; invalidForm = true; } return; + } default: return; } @@ -303,27 +299,7 @@ export const DailyRounds = (props: any) => { if (["NORMAL", "TELEMEDICINE"].includes(state.form.rounds_type)) { data = { ...data, - bp: - state.form.bp?.systolic !== -1 && state.form.bp?.diastolic !== -1 - ? { - systolic: state.form.bp?.systolic - ? Number(state.form.bp?.systolic) - : -1, - diastolic: state.form.bp?.diastolic - ? Number(state.form.bp?.diastolic) - : -1, - mean: - state.form.bp?.systolic && state.form.bp?.diastolic - ? parseFloat( - meanArterialPressure(state.form.bp).toFixed(2) - ) - : -1, - } - : { - systolic: -1, - diastolic: -1, - mean: -1, - }, + bp: state.form.bp ?? {}, pulse: state.form.pulse ?? null, resp: state.form.resp ?? null, temperature: state.form.temperature ?? null, diff --git a/src/Components/Patient/models.tsx b/src/Components/Patient/models.tsx index e1ce5d53050..fc87bedcb14 100644 --- a/src/Components/Patient/models.tsx +++ b/src/Components/Patient/models.tsx @@ -282,9 +282,9 @@ export interface DailyRoundsModel { rhythm?: string; rhythm_detail?: string; bp?: { - diastolic: number; - mean: number; - systolic: number; + diastolic?: number; + mean?: number; + systolic?: number; }; pulse?: number; resp?: number; @@ -297,7 +297,7 @@ export interface DailyRoundsModel { medication_given?: Array; additional_symptoms_text?: string; current_health?: string; - id: string; + id?: string; other_symptoms?: string; admitted_to?: string; patient_category?: PatientCategory; @@ -314,7 +314,7 @@ export interface DailyRoundsModel { | "AGITATED_OR_CONFUSED" | "ONSET_OF_AGITATION_AND_CONFUSION" | "UNKNOWN"; - rounds_type: (typeof DailyRoundTypes)[number]; + rounds_type?: (typeof DailyRoundTypes)[number]; last_updated_by_telemedicine?: boolean; created_by_telemedicine?: boolean; created_by?: { From 7f6cc0c016809768aef236d03429c7021bef46de Mon Sep 17 00:00:00 2001 From: Rithvik Nishad Date: Sat, 6 Jan 2024 20:25:12 +0530 Subject: [PATCH 2/6] hacks/treat-negative-bp-as-undefined (#6987) --- .../Consultations/PrimaryParametersPlot.tsx | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Components/Facility/Consultations/PrimaryParametersPlot.tsx b/src/Components/Facility/Consultations/PrimaryParametersPlot.tsx index 4ff81acf868..ecd3a7d2648 100644 --- a/src/Components/Facility/Consultations/PrimaryParametersPlot.tsx +++ b/src/Components/Facility/Consultations/PrimaryParametersPlot.tsx @@ -17,6 +17,17 @@ interface PrimaryParametersPlotProps { consultationId: string; } +const sanitizeBPAttribute = (value: number | undefined) => { + // Temp. hack until the cleaning of daily rounds as a db migration is done. + // TODO: remove once migration is merged. + + if (value == null || value < 0) { + return; + } + + return value; +}; + export const PrimaryParametersPlot = ({ consultationId, }: PrimaryParametersPlotProps) => { @@ -77,19 +88,19 @@ export const PrimaryParametersPlot = ({ { name: "diastolic", data: Object.values(results) - .map((p: any) => p.bp && p.bp.diastolic) + .map((p: any) => p.bp && sanitizeBPAttribute(p.bp.diastolic)) .reverse(), }, { name: "systolic", data: Object.values(results) - .map((p: any) => p.bp && p.bp.systolic) + .map((p: any) => p.bp && sanitizeBPAttribute(p.bp.systolic)) .reverse(), }, { name: "mean", data: Object.values(results) - .map((p: any) => p.bp && p.bp.mean) + .map((p: any) => p.bp && sanitizeBPAttribute(p.bp.mean)) .reverse(), }, ]; From 37b451a401d510f9ace9b7dca803679b353d30fe Mon Sep 17 00:00:00 2001 From: Gokulram A Date: Mon, 8 Jan 2024 17:39:43 +0530 Subject: [PATCH 3/6] Fix: hide Monitors without a patient checkbox filter is not toggling (#6992) * fix: hide Monitors without a patient checkbox filter is not toggling state * remove state variable isBedOccupied * fix typo * fix boolean qParam being string * fix loading state and bugs * fix initial state --------- Co-authored-by: rithviknishad --- .../Facility/CentralNursingStation.tsx | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/Components/Facility/CentralNursingStation.tsx b/src/Components/Facility/CentralNursingStation.tsx index 75214b5506c..186dbbd48e9 100644 --- a/src/Components/Facility/CentralNursingStation.tsx +++ b/src/Components/Facility/CentralNursingStation.tsx @@ -48,7 +48,8 @@ export default function CentralNursingStation({ facilityId }: Props) { offset: (qParams.page ? qParams.page - 1 : 0) * PER_PAGE_LIMIT, asset_class: "HL7MONITOR", ordering: qParams.ordering || "bed__name", - bed_is_occupied: qParams.bed_is_occupied ?? true, + bed_is_occupied: + (qParams.hide_monitors_without_patient ?? "true") === "true", }, }); @@ -149,19 +150,12 @@ export default function CentralNursingStation({ facilityId }: Props) { errorClassName="hidden" /> { - if (value) { - updateQuery({ [name]: value }); - } else { - removeFilter(name); - } - }} + value={JSON.parse( + qParams.hide_monitors_without_patient ?? true + )} + onChange={(e) => updateQuery({ [e.name]: e.value })} labelClassName="text-sm" errorClassName="hidden" /> @@ -197,7 +191,7 @@ export default function CentralNursingStation({ facilityId }: Props) { } > - {data === undefined ? ( + {data === undefined || query.loading ? ( ) : data.length === 0 ? (
From 557b0d09c70edc944872833941b05a7c3fa88a89 Mon Sep 17 00:00:00 2001 From: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> Date: Tue, 9 Jan 2024 11:11:13 +0530 Subject: [PATCH 4/6] New Cypress Test | Facility Inventory Management | Facility Module (#6979) * inventory management * inventory management error * inventory management error * POM conversion * error --- cypress/e2e/facility_spec/inventory.cy.ts | 56 +++++++++++++++++-- .../pageobject/Facility/FacilityCreation.ts | 50 +++++++++++++++++ src/Components/Facility/InventoryList.tsx | 2 + src/Components/Facility/InventoryLog.tsx | 5 +- src/Components/Facility/MinQuantityList.tsx | 2 + .../Facility/MinQuantityRequiredModal.tsx | 7 ++- 6 files changed, 115 insertions(+), 7 deletions(-) diff --git a/cypress/e2e/facility_spec/inventory.cy.ts b/cypress/e2e/facility_spec/inventory.cy.ts index 79077d6e6a6..e7f1c35cb93 100644 --- a/cypress/e2e/facility_spec/inventory.cy.ts +++ b/cypress/e2e/facility_spec/inventory.cy.ts @@ -1,10 +1,12 @@ 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"; describe("Inventory Management Section", () => { const facilityPage = new FacilityPage(); const loginPage = new LoginPage(); + const facilityHome = new FacilityHome(); before(() => { loginPage.loginAsDisctrictAdmin(); @@ -16,18 +18,64 @@ describe("Inventory Management Section", () => { cy.clearLocalStorage(/filters--.+/); cy.awaitUrl("/"); cy.viewport(1280, 720); - }); - - it("Adds Inventory", () => { facilityPage.visitAlreadyCreatedFacility(); facilityPage.clickManageFacilityDropdown(); facilityPage.clickInventoryManagementOption(); + }); + + it("Add New Inventory | Modify data and delete last entry ", () => { + // add a new item facilityPage.clickManageInventory(); - facilityPage.fillInventoryDetails("Liquid Oxygen", "Add Stock", "120"); + facilityPage.fillInventoryDetails("PPE", "Add Stock", "10"); facilityPage.clickAddInventory(); facilityPage.verifySuccessNotification("Inventory created successfully"); + facilityPage.clickManageInventory(); + // modify the new item + facilityPage.fillInventoryDetails("PPE", "Use Stock", "5"); + facilityPage.clickAddInventory(); + facilityPage.verifySuccessNotification("Inventory created successfully"); + // verify the new modification + facilityPage.verifyPpeQuantity("PPE"); + facilityPage.verifyPpeQuantity("5"); + // delete the last Entry + facilityPage.clickPpeQuantity(); + facilityPage.clickLastEntry(); + // verify the last entry deletion + facilityPage.verifyStockInRow("#row-0", "Added Stock"); + facilityPage.verifyStockInRow("#row-1", "Used Stock"); + cy.wait(3000); + facilityHome.navigateBack(); + facilityPage.verifyPpeQuantity("PPE"); }); + it("Add New Inventory | Verify Backend and manual Minimum", () => { + // Add Inventory + facilityPage.clickManageInventory(); + facilityPage.fillInventoryDetails("PPE", "Add Stock", "5"); + facilityPage.clickAddInventory(); + facilityPage.verifySuccessNotification("Inventory created successfully"); + // Verify Backend minimum badge + facilityPage.verifyBadgeWithText(".badge-danger", "Low Stock"); + // modify with manual minimum badge + facilityPage.clickAddMinimumQuanitity(); + cy.wait(3000); + cy.get("body").then(($body) => { + if ($body.find("#update-minimum-quantity").is(":visible")) { + // If the 'update-minimum-quantity' element is visible, click it + facilityPage.clickUpdateMinimumQuantity(); + facilityPage.setQuantity("5"); + facilityPage.clickSaveUpdateMinimumQuantity(); + } else { + // Otherwise, click the 'set-minimum-quantity' element + facilityPage.clickSetMinimumQuantity(); + facilityPage.fillInventoryMinimumDetails("PPE", "1"); + facilityPage.clickSetButton(); + facilityPage.verifySuccessNotification( + "Minimum quantiy updated successfully" + ); + } + }); + }); afterEach(() => { cy.saveLocalStorage(); }); diff --git a/cypress/pageobject/Facility/FacilityCreation.ts b/cypress/pageobject/Facility/FacilityCreation.ts index 2d6aa9ff375..bb6cf0e19f2 100644 --- a/cypress/pageobject/Facility/FacilityCreation.ts +++ b/cypress/pageobject/Facility/FacilityCreation.ts @@ -372,6 +372,12 @@ class FacilityPage { cy.get("[name='quantity']").type(quantity); } + fillInventoryMinimumDetails(name: string, quantity: string) { + cy.get("div#id").click(); + cy.get("div#id ul li").contains(name).click(); + cy.get("[name='quantity']").type(quantity); + } + clickAddInventory() { cy.intercept("POST", "**/api/v1/facility/*/inventory/").as( "createInventory" @@ -380,6 +386,10 @@ class FacilityPage { cy.wait("@createInventory").its("response.statusCode").should("eq", 201); } + clickSetButton() { + cy.get("#submit").contains("Set").click(); + } + fillResourceRequestDetails( name: string, phone_number: string, @@ -443,6 +453,46 @@ class FacilityPage { } }); } + + verifyPpeQuantity(text: string) { + cy.get("#PPE").contains(text).should("be.visible"); + } + + clickPpeQuantity() { + cy.get("#PPE").click(); + } + + clickLastEntry() { + cy.get("#delete-last-entry").click(); + } + + verifyStockInRow(rowId: string, stockText: string) { + cy.get(rowId).contains(stockText).should("be.visible"); + } + + verifyBadgeWithText(badgeClass: string, text: string) { + cy.get(badgeClass).contains(text).should("exist"); + } + + clickAddMinimumQuanitity() { + cy.get("#add-minimum-quantity").click(); + } + + clickUpdateMinimumQuantity() { + cy.get("#update-minimum-quantity").first().click(); + } + + setQuantity(quantity: string) { + cy.get("#quantity").click().clear().click().type(quantity); + } + + clickSaveUpdateMinimumQuantity() { + cy.get("#save-update-minimumquanitity").click(); + } + + clickSetMinimumQuantity() { + cy.get("#set-minimum-quantity").click(); + } } export default FacilityPage; diff --git a/src/Components/Facility/InventoryList.tsx b/src/Components/Facility/InventoryList.tsx index 26f1af87191..837b0b2ce2a 100644 --- a/src/Components/Facility/InventoryList.tsx +++ b/src/Components/Facility/InventoryList.tsx @@ -71,6 +71,7 @@ export default function InventoryList(props: any) { if (inventory?.length) { inventoryList = inventory.map((inventoryItem: any) => ( diff --git a/src/Components/Facility/InventoryLog.tsx b/src/Components/Facility/InventoryLog.tsx index 5518b5e320f..8369a7d1562 100644 --- a/src/Components/Facility/InventoryLog.tsx +++ b/src/Components/Facility/InventoryLog.tsx @@ -117,8 +117,8 @@ export default function InventoryLog(props: any) { let inventoryList: any = []; if (inventory?.length) { - inventoryList = inventory.map((inventoryItem: any) => ( - + inventoryList = inventory.map((inventoryItem: any, index) => ( +
@@ -270,6 +270,7 @@ export default function InventoryLog(props: any) { as accident.
removeLastInventoryLog(inventory[0].item_object.id) diff --git a/src/Components/Facility/MinQuantityList.tsx b/src/Components/Facility/MinQuantityList.tsx index 631f432a9dc..941722bd810 100644 --- a/src/Components/Facility/MinQuantityList.tsx +++ b/src/Components/Facility/MinQuantityList.tsx @@ -126,6 +126,7 @@ export default function MinQuantityList(props: any) { {inventoryItem.item_object?.default_unit?.name}

{ />
- + Update From cc3886007e46c41f908567e0a32438785eedcfd0 Mon Sep 17 00:00:00 2001 From: Aditya Pachauri <103623274+AdityyaX@users.noreply.github.com> Date: Wed, 10 Jan 2024 13:25:44 +0530 Subject: [PATCH 5/6] Updated DOB Date Format in Patient details page (#6950) * date format changed * Update src/Components/Patient/PatientHome.tsx Co-authored-by: Rithvik Nishad * Update src/Components/Patient/PatientHome.tsx Co-authored-by: Rithvik Nishad * fix imports --------- Co-authored-by: Rithvik Nishad Co-authored-by: rithviknishad --- src/Components/Patient/PatientHome.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Components/Patient/PatientHome.tsx b/src/Components/Patient/PatientHome.tsx index 22edfb16192..32118e5951e 100644 --- a/src/Components/Patient/PatientHome.tsx +++ b/src/Components/Patient/PatientHome.tsx @@ -19,7 +19,12 @@ import { ConsultationModel } from "../Facility/models"; import { PatientModel, SampleTestModel } from "./models"; import { SampleTestCard } from "./SampleTestCard"; import Chip from "../../CAREUI/display/Chip"; -import { classNames, formatAge, formatDateTime } from "../../Utils/utils"; +import { + classNames, + formatAge, + formatDate, + formatDateTime, +} from "../../Utils/utils"; import ButtonV2 from "../Common/components/ButtonV2"; import { NonReadOnlyUsers } from "../../Utils/AuthorizeFor"; import RelativeDateUserMention from "../Common/RelativeDateUserMention"; @@ -570,7 +575,7 @@ export const PatientHome = (props: any) => { Date of Birth
- {patientData?.date_of_birth} + {formatDate(patientData?.date_of_birth)}
From 197cb39f42ea578922db0f45983e842613454ce0 Mon Sep 17 00:00:00 2001 From: Rithvik Nishad Date: Wed, 10 Jan 2024 13:28:10 +0530 Subject: [PATCH 6/6] Migrate `useDispatch` with `useQuery/request` in `src/Components/Common/**` (#6889) * Migrate to `useQuery` in `AssetSelect` * Migrate `useQuery` in `BedSelect` * Migrate `useQuery` in `DistrictAutocompleteFormField` * Migrate `useQuery` in `StateAutocompleteFormField` * Migrate `useQuery` in `LocalBodyAutocompleteFormField` * Migrate `useQuery` in `FacilitySelect` * Migrate `useQuery` in `LocationSelect` * Migrate `useQuery` in `SkillSelect` * Migrate `useQuery` in `InvestigationBuilder` * Migrate `useQuery` in `Uptime` (Asset) * fix location select not working for single select * uptime: fix issue with reverse --- src/Components/Common/AssetSelect.tsx | 28 ++---- src/Components/Common/BedSelect.tsx | 24 +++-- .../Common/DistrictAutocompleteFormField.tsx | 46 +++------- src/Components/Common/FacilitySelect.tsx | 20 ++--- .../Common/LocalBodyAutocompleteFormField.tsx | 48 +++------- src/Components/Common/LocationSelect.tsx | 89 +++++++------------ src/Components/Common/SkillSelect.tsx | 25 ++---- .../Common/StateAutocompleteFormField.tsx | 36 ++------ src/Components/Common/Uptime.tsx | 42 +++------ .../InvestigationBuilder.tsx | 37 +++----- src/Components/Facility/AssetCreate.tsx | 2 +- src/Components/Facility/ConsultationForm.tsx | 13 ++- .../Facility/Investigations/Reports/index.tsx | 4 +- .../Facility/Investigations/index.tsx | 12 +-- src/Components/Facility/models.tsx | 10 ++- src/Components/Users/SkillsSlideOver.tsx | 2 - src/Redux/actions.tsx | 15 +--- src/Redux/api.tsx | 12 ++- 18 files changed, 156 insertions(+), 309 deletions(-) diff --git a/src/Components/Common/AssetSelect.tsx b/src/Components/Common/AssetSelect.tsx index 0e47c7cfbfd..3f4f928032d 100644 --- a/src/Components/Common/AssetSelect.tsx +++ b/src/Components/Common/AssetSelect.tsx @@ -1,7 +1,7 @@ import { useCallback } from "react"; -import { useDispatch } from "react-redux"; -import { listAssets } from "../../Redux/actions"; import AutoCompleteAsync from "../Form/AutoCompleteAsync"; +import routes from "../../Redux/api"; +import request from "../../Utils/request/request"; interface AssetSelectProps { name: string; @@ -16,7 +16,6 @@ interface AssetSelectProps { asset_class?: string; showAll?: boolean; showNOptions?: number; - freeText?: boolean; selected: any; setSelected: (selected: any) => void; } @@ -33,21 +32,13 @@ export const AssetSelect = (props: AssetSelectProps) => { is_permanent = null, showNOptions = 10, className = "", - freeText = false, errors = "", asset_class = "", } = props; - const dispatchAction: any = useDispatch(); - const AssetSearch = useCallback( async (text: string) => { - const params: Partial & { - limit: number; - offset: number; - search_text: string; - asset_class: string; - } = { + const query = { limit: 50, offset: 0, search_text: text, @@ -56,17 +47,12 @@ export const AssetSelect = (props: AssetSelectProps) => { in_use_by_consultation, is_permanent, asset_class, - }; + } as const; - const res = await dispatchAction(listAssets(params)); - if (freeText) - res?.data?.results?.push({ - id: -1, - name: text, - }); - return res?.data?.results; + const { data } = await request(routes.listAssets, { query }); + return data?.results; }, - [dispatchAction] + [asset_class, facility, in_use_by_consultation, is_permanent, is_working] ); return ( diff --git a/src/Components/Common/BedSelect.tsx b/src/Components/Common/BedSelect.tsx index 94caded12a3..a548b7a9eb5 100644 --- a/src/Components/Common/BedSelect.tsx +++ b/src/Components/Common/BedSelect.tsx @@ -1,9 +1,9 @@ import { useCallback } from "react"; -import { useDispatch } from "react-redux"; -import { listFacilityBeds } from "../../Redux/actions"; import { BedModel } from "../Facility/models"; import AutoCompleteAsync from "../Form/AutoCompleteAsync"; import { useTranslation } from "react-i18next"; +import request from "../../Utils/request/request"; +import routes from "../../Redux/api"; interface BedSelectProps { name: string; @@ -34,13 +34,11 @@ export const BedSelect = (props: BedSelectProps) => { location, showNOptions = 20, } = props; - - const dispatchAction: any = useDispatch(); const { t } = useTranslation(); const onBedSearch = useCallback( async (text: string) => { - const params = { + const query = { limit: 50, offset: 0, search_text: text, @@ -49,17 +47,17 @@ export const BedSelect = (props: BedSelectProps) => { location, }; - const res = await dispatchAction(listFacilityBeds(params)); - if (res && res.data) { - let beds = res.data.results; - if (unoccupiedOnly) { - beds = beds.filter((bed: BedModel) => bed?.is_occupied === false); - } + const { data } = await request(routes.listFacilityBeds, { query }); - return beds; + if (unoccupiedOnly) { + return data?.results?.filter( + (bed: BedModel) => bed?.is_occupied === false + ); } + + return data?.results; }, - [dispatchAction, facility, location, searchAll, unoccupiedOnly] + [facility, location, searchAll, unoccupiedOnly] ); return ( diff --git a/src/Components/Common/DistrictAutocompleteFormField.tsx b/src/Components/Common/DistrictAutocompleteFormField.tsx index 122b576a2fc..dbee6c9f08d 100644 --- a/src/Components/Common/DistrictAutocompleteFormField.tsx +++ b/src/Components/Common/DistrictAutocompleteFormField.tsx @@ -1,51 +1,27 @@ -import { useDispatch } from "react-redux"; import { FormFieldBaseProps } from "../Form/FormFields/Utils"; -import { IState } from "./StateAutocompleteFormField"; import AutocompleteFormField from "../Form/FormFields/Autocomplete"; -import { statusType, useAbortableEffect } from "../../Common/utils"; -import { useCallback, useState } from "react"; -import { getDistrictByState } from "../../Redux/actions"; +import useQuery from "../../Utils/request/useQuery"; +import routes from "../../Redux/api"; +import { DistrictModel, StateModel } from "../Facility/models"; -export type IDistrict = { - id: number; - name: string; -}; - -type Props = FormFieldBaseProps & { +type Props = FormFieldBaseProps & { placeholder?: string; - state?: IState["id"]; + state?: StateModel["id"]; }; export default function DistrictAutocompleteFormField(props: Props) { - const dispatch = useDispatch(); - const [districts, setDistricts] = useState(); - - const fetchDistricts = useCallback( - async (status: any) => { - setDistricts(undefined); - if (!props.state) { - return; - } - const res = await dispatch(getDistrictByState({ id: props.state })); - if (!status.aborted && res.data) { - setDistricts(res.data); - } - }, - [dispatch, props.state] - ); - - useAbortableEffect( - (status: statusType) => fetchDistricts(status), - [props.state] - ); + const { data, loading } = useQuery(routes.getDistrictByState, { + pathParams: { id: props.state?.toString() ?? "" }, + prefetch: props.state !== undefined, + }); return ( option.name} optionValue={(option) => option.id} - isLoading={!!(props.state && districts === undefined)} + isLoading={loading} disabled={!props.state} /> ); diff --git a/src/Components/Common/FacilitySelect.tsx b/src/Components/Common/FacilitySelect.tsx index 1aabc36013b..17f67a7def1 100644 --- a/src/Components/Common/FacilitySelect.tsx +++ b/src/Components/Common/FacilitySelect.tsx @@ -1,8 +1,8 @@ import { useCallback } from "react"; -import { useDispatch } from "react-redux"; -import { getAllFacilities, getPermittedFacilities } from "../../Redux/actions"; import AutoCompleteAsync from "../Form/AutoCompleteAsync"; import { FacilityModel } from "../Facility/models"; +import request from "../../Utils/request/request"; +import routes from "../../Redux/api"; interface FacilitySelectProps { name: string; @@ -37,11 +37,9 @@ export const FacilitySelect = (props: FacilitySelectProps) => { errors = "", } = props; - const dispatchAction: any = useDispatch(); - const facilitySearch = useCallback( async (text: string) => { - const params = { + const query = { limit: 50, offset: 0, search_text: text, @@ -51,17 +49,19 @@ export const FacilitySelect = (props: FacilitySelectProps) => { district, }; - const res = await dispatchAction( - showAll ? getAllFacilities(params) : getPermittedFacilities(params) + const { data } = await request( + showAll ? routes.getAllFacilities : routes.getPermittedFacilities, + { query } ); + if (freeText) - res?.data?.results?.push({ + data?.results?.push({ id: -1, name: text, }); - return res?.data?.results; + return data?.results; }, - [dispatchAction, searchAll, showAll, facilityType, district] + [searchAll, showAll, facilityType, district, exclude_user, freeText] ); return ( diff --git a/src/Components/Common/LocalBodyAutocompleteFormField.tsx b/src/Components/Common/LocalBodyAutocompleteFormField.tsx index eacfbc35b89..32023fa559f 100644 --- a/src/Components/Common/LocalBodyAutocompleteFormField.tsx +++ b/src/Components/Common/LocalBodyAutocompleteFormField.tsx @@ -1,53 +1,27 @@ -import { useDispatch } from "react-redux"; import { FormFieldBaseProps } from "../Form/FormFields/Utils"; import AutocompleteFormField from "../Form/FormFields/Autocomplete"; -import { statusType, useAbortableEffect } from "../../Common/utils"; -import { useCallback, useState } from "react"; -import { getLocalbodyByDistrict } from "../../Redux/actions"; -import { IDistrict } from "./DistrictAutocompleteFormField"; +import { DistrictModel, LocalBodyModel } from "../Facility/models"; +import useQuery from "../../Utils/request/useQuery"; +import routes from "../../Redux/api"; -export type ILocalBody = { - id: number; - name: string; -}; - -type Props = FormFieldBaseProps & { +type Props = FormFieldBaseProps & { placeholder?: string; - district?: IDistrict["id"]; + district?: DistrictModel["id"]; }; export default function LocalBodyAutocompleteFormField(props: Props) { - const dispatch = useDispatch(); - const [localBodies, setLocalBodies] = useState(); - - const fetchLocalBodies = useCallback( - async (status: any) => { - setLocalBodies(undefined); - if (!props.district) { - return; - } - const res = await dispatch( - getLocalbodyByDistrict({ id: props.district }) - ); - if (!status.aborted && res && res.data) { - setLocalBodies(res.data); - } - }, - [dispatch, props.district] - ); - - useAbortableEffect( - (status: statusType) => fetchLocalBodies(status), - [props.district] - ); + const { data, loading } = useQuery(routes.getLocalbodyByDistrict, { + pathParams: { id: props.district?.toString() ?? "" }, + prefetch: props.district !== undefined, + }); return ( option.name} optionValue={(option) => option.id} - isLoading={!!(props.district && localBodies === undefined)} + isLoading={loading} disabled={!props.district} /> ); diff --git a/src/Components/Common/LocationSelect.tsx b/src/Components/Common/LocationSelect.tsx index d20c843fad8..dcade42a596 100644 --- a/src/Components/Common/LocationSelect.tsx +++ b/src/Components/Common/LocationSelect.tsx @@ -1,8 +1,7 @@ -import { useEffect, useState } from "react"; -import { useDispatch } from "react-redux"; -import { listFacilityAssetLocation } from "../../Redux/actions"; import AutocompleteFormField from "../Form/FormFields/Autocomplete"; import AutocompleteMultiSelectFormField from "../Form/FormFields/AutocompleteMultiselect"; +import useQuery from "../../Utils/request/useQuery"; +import routes from "../../Redux/api"; interface LocationSelectProps { name: string; disabled?: boolean; @@ -11,7 +10,7 @@ interface LocationSelectProps { className?: string; searchAll?: boolean; multiple?: boolean; - facilityId: number | string; + facilityId: string; showAll?: boolean; selected: string | string[] | null; setSelected: (selected: string | string[] | null) => void; @@ -19,76 +18,48 @@ interface LocationSelectProps { } export const LocationSelect = (props: LocationSelectProps) => { - const { - name, - multiple, - selected, - setSelected, - errors, - className = "", - facilityId, - disabled = false, - } = props; - const [locations, setLocations] = useState<{ name: string; id: string }[]>( - [] + const { data, loading, refetch } = useQuery( + routes.listFacilityAssetLocation, + { + query: { + limit: 14, + }, + pathParams: { + facility_external_id: props.facilityId, + }, + prefetch: props.facilityId !== undefined, + } ); - const [query, setQuery] = useState(""); - const [loading, setLoading] = useState(false); - const dispatchAction: any = useDispatch(); - - const handleValueChange = (current: string[]) => { - if (multiple) setSelected(current); - else setSelected(current ? current[0] : ""); - }; - - useEffect(() => { - if (!facilityId) return; - const params = { - limit: 14, - search_text: query, - }; - setLoading(true); - dispatchAction( - listFacilityAssetLocation(params, { facility_external_id: facilityId }) - ).then(({ data }: any) => { - setLocations(data.results); - setLoading(false); - }); - }, [query, facilityId]); return props.multiple ? ( handleValueChange(value as unknown as string[])} - onQuery={(query) => { - setQuery(query); - }} + name={props.name} + disabled={props.disabled} + value={props.selected as unknown as string[]} + options={data?.results ?? []} + onChange={({ value }) => props.setSelected(value)} + onQuery={(search_text) => refetch({ query: { search_text } })} placeholder="Search by location name" optionLabel={(option) => option.name} optionValue={(option) => option.id} - error={errors} - className={className} + error={props.errors} + className={props.className} errorClassName={props.errorClassName} /> ) : ( handleValueChange([value])} - onQuery={(query) => { - setQuery(query); - }} + name={props.name} + disabled={props.disabled} + value={props.selected as string} + options={data?.results ?? []} + onChange={({ value }) => props.setSelected(value)} + onQuery={(search_text) => refetch({ query: { search_text } })} isLoading={loading} placeholder="Search by location name" optionLabel={(option) => option.name} optionValue={(option) => option.id} - error={errors} - className={className} + error={props.errors} + className={props.className} errorClassName={props.errorClassName} /> ); diff --git a/src/Components/Common/SkillSelect.tsx b/src/Components/Common/SkillSelect.tsx index 941c29790d1..e0d9aafdb13 100644 --- a/src/Components/Common/SkillSelect.tsx +++ b/src/Components/Common/SkillSelect.tsx @@ -1,8 +1,8 @@ import { useCallback } from "react"; -import { useDispatch } from "react-redux"; -import { getAllSkills } from "../../Redux/actions"; import AutoCompleteAsync from "../Form/AutoCompleteAsync"; import { SkillModel, SkillObjectModel } from "../Users/models"; +import request from "../../Utils/request/request"; +import routes from "../../Redux/api"; interface SkillSelectProps { id?: string; @@ -11,12 +11,10 @@ interface SkillSelectProps { className?: string; searchAll?: boolean; multiple?: boolean; - showAll?: boolean; showNOptions?: number; disabled?: boolean; selected: SkillObjectModel | SkillObjectModel[] | null; setSelected: (selected: SkillObjectModel) => void; - username?: string; userSkills?: SkillModel[]; } @@ -28,37 +26,28 @@ export const SkillSelect = (props: SkillSelectProps) => { selected, setSelected, searchAll, - showAll = true, showNOptions = 10, disabled = false, className = "", errors = "", - //username, userSkills, } = props; - const dispatchAction: any = useDispatch(); - const skillSearch = useCallback( async (text: string) => { - const params = { + const query = { limit: 50, offset: 0, search_text: text, all: searchAll, }; - const res = await dispatchAction(getAllSkills(params)); - const skillsID: string[] = []; - userSkills?.map((skill: SkillModel) => - skillsID.push(skill.skill_object.id) - ); - const skills = res?.data?.results.filter( - (skill: any) => !skillsID.includes(skill.id) + const { data } = await request(routes.getAllSkills, { query }); + return data?.results.filter( + (skill) => !userSkills?.some((userSkill) => userSkill.id === skill.id) ); - return skills; }, - [dispatchAction, searchAll, userSkills, showAll] + [searchAll, userSkills] ); return ( diff --git a/src/Components/Common/StateAutocompleteFormField.tsx b/src/Components/Common/StateAutocompleteFormField.tsx index 384f46c3a7c..77d52768198 100644 --- a/src/Components/Common/StateAutocompleteFormField.tsx +++ b/src/Components/Common/StateAutocompleteFormField.tsx @@ -1,45 +1,23 @@ -import { useCallback, useState } from "react"; import AutocompleteFormField from "../Form/FormFields/Autocomplete"; import { FormFieldBaseProps } from "../Form/FormFields/Utils"; -import { statusType, useAbortableEffect } from "../../Common/utils"; -import { useDispatch } from "react-redux"; -import { getStates } from "../../Redux/actions"; +import { StateModel } from "../Facility/models"; +import useQuery from "../../Utils/request/useQuery"; +import routes from "../../Redux/api"; -export type IState = { - id: number; - name: string; -}; - -type Props = FormFieldBaseProps & { +type Props = FormFieldBaseProps & { placeholder?: string; }; export default function StateAutocompleteFormField(props: Props) { - const dispatch = useDispatch(); - const [states, setStates] = useState(); - - const fetchStates = useCallback( - async (status: any) => { - setStates(undefined); - const res = await dispatch(getStates()); - if (!status.aborted && res && res.data) { - setStates(res.data.results); - } - }, - [dispatch] - ); - - useAbortableEffect((status: statusType) => { - fetchStates(status); - }, []); + const { data, loading } = useQuery(routes.statesList); return ( option.name} optionValue={(option) => option.id} - isLoading={states === undefined} + isLoading={loading} /> ); } diff --git a/src/Components/Common/Uptime.tsx b/src/Components/Common/Uptime.tsx index 6f6966b9053..e3c7dd7a439 100644 --- a/src/Components/Common/Uptime.tsx +++ b/src/Components/Common/Uptime.tsx @@ -1,12 +1,10 @@ import { Popover } from "@headlessui/react"; -import { useCallback, useEffect, useRef, useState } from "react"; -import { listAssetAvailability } from "../../Redux/actions"; -import { useDispatch } from "react-redux"; -import * as Notification from "../../Utils/Notifications.js"; +import { useEffect, useRef, useState } from "react"; import { AssetStatus, AssetUptimeRecord } from "../Assets/AssetTypes"; -import { reverse } from "lodash-es"; import { classNames } from "../../Utils/utils"; import dayjs from "../../Utils/dayjs"; +import useQuery from "../../Utils/request/useQuery.js"; +import routes from "../../Redux/api.js"; const STATUS_COLORS = { Operational: "bg-green-500", @@ -63,7 +61,7 @@ function UptimeInfo({ <> Status Updates
- {reverse(incidents)?.map((incident, index) => { + {incidents.reverse().map((incident, index) => { const prevIncident = incidents[index - 1]; let endTimestamp; let ongoing = false; @@ -171,16 +169,16 @@ export default function Uptime(props: { assetId: string }) { const [summary, setSummary] = useState<{ [key: number]: AssetUptimeRecord[]; }>([]); - const [availabilityData, setAvailabilityData] = useState( - [] - ); - const [loading, setLoading] = useState(true); + const { data, loading } = useQuery(routes.listAssetAvailability, { + query: { external_id: props.assetId }, + onResponse: ({ data }) => setUptimeRecord(data?.results.reverse() ?? []), + }); + const availabilityData = data?.results ?? []; const graphElem = useRef(null); const [numDays, setNumDays] = useState( Math.floor((window.innerWidth - 1024) / 20) ); const [hoveredDay, setHoveredDay] = useState(-1); - const dispatch = useDispatch(); const handleResize = () => { const containerWidth = graphElem.current?.clientWidth ?? window.innerWidth; @@ -268,25 +266,6 @@ export default function Uptime(props: { assetId: string }) { return Math.round((upStatus / (days * 3)) * 100); } - const fetchData = useCallback(async () => { - setLoading(true); - setLoading(false); - - const availabilityData = await dispatch( - listAssetAvailability({ - external_id: props.assetId, - }) - ); - if (availabilityData?.data) { - setAvailabilityData(availabilityData.data.results); - setUptimeRecord(reverse(availabilityData.data.results)); - } else { - Notification.Error({ - msg: "Error fetching availability history", - }); - } - }, [dispatch, props.assetId]); - useEffect(() => { setTimeout(() => { handleResize(); @@ -297,8 +276,7 @@ export default function Uptime(props: { assetId: string }) { useEffect(() => { handleResize(); - fetchData(); - }, [props.assetId, fetchData]); + }, []); const getStatusColor = (day: number) => { if (summary[day]) { diff --git a/src/Components/Common/prescription-builder/InvestigationBuilder.tsx b/src/Components/Common/prescription-builder/InvestigationBuilder.tsx index 67ac412c2e0..cb0bbac1f66 100644 --- a/src/Components/Common/prescription-builder/InvestigationBuilder.tsx +++ b/src/Components/Common/prescription-builder/InvestigationBuilder.tsx @@ -1,12 +1,10 @@ import { useEffect, useState } from "react"; -import { useDispatch } from "react-redux"; -import { - listInvestigationGroups, - listInvestigations, -} from "../../../Redux/actions"; import { PrescriptionDropdown } from "./PrescriptionDropdown"; import { PrescriptionMultiDropdown } from "./PrescriptionMultiselect"; import CareIcon from "../../../CAREUI/icons/CareIcon"; +import request from "../../../Utils/request/request"; +import routes from "../../../Redux/api"; + export type InvestigationType = { type?: string[]; repetitive?: boolean; @@ -35,7 +33,6 @@ export default function InvestigationBuilder( ) { const { investigations, setInvestigations } = props; const [investigationsList, setInvestigationsList] = useState([]); - const dispatch: any = useDispatch(); const [activeIdx, setActiveIdx] = useState(null); const additionalInvestigations = [ ["Vitals", ["Temp", "Blood Pressure", "Respiratory Rate", "Pulse Rate"]], @@ -85,26 +82,20 @@ export default function InvestigationBuilder( }; const fetchInvestigations = async () => { - const res = await dispatch(listInvestigations({})); - if (res && res.data) { - return res.data.results.map( - (investigation: any) => - investigation.name + - " -- " + - investigation.groups - .map((group: any) => " ( " + group.name + " ) ") - .join(", ") - ); - } - return []; + const { data } = await request(routes.listInvestigations); + return ( + data?.results.map( + (investigation) => + `${investigation.name} -- ${investigation.groups + .map((group) => ` ( ${group.name} ) `) + .join(", ")}` + ) ?? [] + ); }; const fetchInvestigationGroups = async () => { - const res = await dispatch(listInvestigationGroups({})); - if (res && res.data) { - return res.data.results.map((group: any) => group.name + " (GROUP)"); - } - return []; + const { data } = await request(routes.listInvestigationGroups); + return data?.results.map((group) => `${group.name} (GROUP)`) ?? []; }; return ( diff --git a/src/Components/Facility/AssetCreate.tsx b/src/Components/Facility/AssetCreate.tsx index a1e06a8c7ab..35f71a746fd 100644 --- a/src/Components/Facility/AssetCreate.tsx +++ b/src/Components/Facility/AssetCreate.tsx @@ -563,7 +563,7 @@ const AssetCreate = (props: AssetProps) => { selected={location} showAll={false} multiple={false} - facilityId={facilityId as unknown as number} + facilityId={facilityId} errors={state.errors.location} />
diff --git a/src/Components/Facility/ConsultationForm.tsx b/src/Components/Facility/ConsultationForm.tsx index 77962cc7703..63e18645e13 100644 --- a/src/Components/Facility/ConsultationForm.tsx +++ b/src/Components/Facility/ConsultationForm.tsx @@ -229,11 +229,16 @@ type ConsultationFormSection = | "Treatment Plan" | "Bed Status"; -export const ConsultationForm = (props: any) => { +type Props = { + facilityId: string; + patientId: string; + id?: string; +}; + +export const ConsultationForm = ({ facilityId, patientId, id }: Props) => { const { goBack } = useAppHistory(); const { kasp_enabled, kasp_string } = useConfig(); const dispatchAction: any = useDispatch(); - const { facilityId, patientId, id } = props; const [state, dispatch] = useAutoSaveReducer( consultationFormReducer, initialState @@ -344,7 +349,7 @@ export const ConsultationForm = (props: any) => { const fetchData = useCallback( async (status: statusType) => { if (!patientId) setIsLoading(true); - const res = await dispatchAction(getConsultation(id)); + const res = await dispatchAction(getConsultation(id!)); handleFormFieldChange({ name: "InvestigationAdvice", value: !Array.isArray(res.data.investigation) @@ -743,7 +748,7 @@ export const ConsultationForm = (props: any) => { }; const res = await dispatchAction( - id ? updateConsultation(id, data) : createConsultation(data) + id ? updateConsultation(id!, data) : createConsultation(data) ); setIsLoading(false); if (res?.data && res.status !== 400) { diff --git a/src/Components/Facility/Investigations/Reports/index.tsx b/src/Components/Facility/Investigations/Reports/index.tsx index 9b3c29d40f8..b868e8e8af0 100644 --- a/src/Components/Facility/Investigations/Reports/index.tsx +++ b/src/Components/Facility/Investigations/Reports/index.tsx @@ -1,6 +1,6 @@ import * as Notification from "../../../../Utils/Notifications"; import _ from "lodash-es"; -import { Group, InvestigationType } from ".."; +import { InvestigationGroup, InvestigationType } from ".."; import { getPatient, getPatientInvestigation, @@ -22,7 +22,7 @@ import { useRef } from "react"; const RESULT_PER_PAGE = 14; interface InitialState { - investigationGroups: Group[]; + investigationGroups: InvestigationGroup[]; selectedGroup: string[]; investigations: InvestigationType[]; selectedInvestigations: any[]; diff --git a/src/Components/Facility/Investigations/index.tsx b/src/Components/Facility/Investigations/index.tsx index 91836b6bbec..95147ec4c89 100644 --- a/src/Components/Facility/Investigations/index.tsx +++ b/src/Components/Facility/Investigations/index.tsx @@ -22,7 +22,7 @@ const initialState = { form: {}, }; -export interface Group { +export interface InvestigationGroup { external_id: string; name: string; } @@ -38,9 +38,9 @@ export interface InvestigationType { unit?: string; choices?: string; ideal_value?: string; - groups: Group[]; + groups: InvestigationGroup[]; } -type SearchItem = Group | InvestigationType; +type SearchItem = InvestigationGroup | InvestigationType; function isInvestigation(e: SearchItem): e is InvestigationType { return (e as InvestigationType).groups !== undefined; } @@ -67,7 +67,7 @@ const listOfInvestigations = ( ); }; -const findGroup = (group_id: string, groups: Group[]) => { +const findGroup = (group_id: string, groups: InvestigationGroup[]) => { return groups.find((g) => g.external_id === group_id); }; @@ -106,7 +106,9 @@ const Investigation = (props: { const [selectedGroup, setSelectedGroup] = useState([]); const [state, setState] = useReducer(testFormReducer, initialState); const [investigations, setInvestigations] = useState([]); - const [investigationGroups, setInvestigationGroups] = useState([]); + const [investigationGroups, setInvestigationGroups] = useState< + InvestigationGroup[] + >([]); const [selectedInvestigations, setSelectedInvestigations] = useState< InvestigationType[] >([]); diff --git a/src/Components/Facility/models.tsx b/src/Components/Facility/models.tsx index c3ac910970c..f26f458d4ca 100644 --- a/src/Components/Facility/models.tsx +++ b/src/Components/Facility/models.tsx @@ -203,11 +203,11 @@ export interface InventoryItemsModel { } export interface LocationModel { - id?: string; - name?: string; + id: string; + name: string; description?: string; middleware_address?: string; - location_type?: AssetLocationType; + location_type: AssetLocationType; facility?: { name: string; }; @@ -218,8 +218,8 @@ export interface LocationModel { export interface BedModel { id?: string; bed_type?: string; - description?: string; name?: string; + description?: string; facility?: string; location_object?: { name: string; @@ -227,6 +227,8 @@ export interface BedModel { }; location?: string; is_occupied?: boolean; + created_date?: string; + modified_date?: string; } export interface CurrentBed { diff --git a/src/Components/Users/SkillsSlideOver.tsx b/src/Components/Users/SkillsSlideOver.tsx index 1819333451d..63353479f0d 100644 --- a/src/Components/Users/SkillsSlideOver.tsx +++ b/src/Components/Users/SkillsSlideOver.tsx @@ -115,12 +115,10 @@ export default ({ show, setShow, username }: IProps) => { multiple={false} name="skill" disabled={!authorizeForAddSkill} - showAll={true} showNOptions={Infinity} selected={selectedSkill} setSelected={setSelectedSkill} errors="" - username={username} userSkills={skills?.results || []} /> { return fireRequest("getPermittedFacilities", [], params); }; -export const getAllFacilities = (params: object) => { - return fireRequest("getAllFacilities", [], params); -}; - -export const getAllSkills = (params: object) => { - return fireRequest("getAllSkills", [], params); -}; - export const getAnyFacility = (id: number | string, key?: string) => { return fireRequest("getAnyFacility", [], {}, { id: id }, key); }; @@ -296,10 +288,10 @@ export const createConsultation = (params: object) => { export const getConsultationList = (params: object) => { return fireRequest("getConsultationList", [], params); }; -export const getConsultation = (id: number) => { +export const getConsultation = (id: string) => { return fireRequest("getConsultation", [], {}, { id: id }); }; -export const updateConsultation = (id: number, params: object) => { +export const updateConsultation = (id: string, params: object) => { return fireRequest("updateConsultation", [], params, { id: id }); }; //Inventory @@ -506,9 +498,6 @@ export const updateAsset = (id: string, params: object) => export const operateAsset = (id: string, params: object) => fireRequest("operateAsset", [], params, { external_id: id }); -export const listAssetAvailability = (params: object) => - fireRequest("listAssetAvailability", [], params); - export const listPMJYPackages = (query?: string) => fireRequest("listPMJYPackages", [], { query }); diff --git a/src/Redux/api.tsx b/src/Redux/api.tsx index 8f8fc76484d..db049b1ed71 100644 --- a/src/Redux/api.tsx +++ b/src/Redux/api.tsx @@ -27,6 +27,7 @@ import { AssetServiceUpdate, AssetTransaction, AssetUpdate, + AssetUptimeRecord, PatientAssetBed, } from "../Components/Assets/AssetTypes"; import { @@ -77,6 +78,10 @@ import { import { IComment, IResource } from "../Components/Resource/models"; import { IShift } from "../Components/Shifting/models"; import { HCXPolicyModel } from "../Components/HCX/models"; +import { + InvestigationGroup, + InvestigationType, +} from "../Components/Facility/Investigations"; /** * A fake function that returns an empty object casted to type T @@ -286,6 +291,7 @@ const routes = { getAllFacilities: { path: "/api/v1/getallfacilities", + TRes: Type>(), }, createFacility: { @@ -933,10 +939,12 @@ const routes = { listInvestigations: { path: "/api/v1/investigation/", method: "GET", + TRes: Type>(), }, listInvestigationGroups: { - path: "/api/v1/investigation/group", + path: "/api/v1/investigation/group/", method: "GET", + TRes: Type>(), }, createInvestigation: { path: "/api/v1/consultation/{consultation_external_id}/investigation/", @@ -1232,10 +1240,12 @@ const routes = { listAssetAvailability: { path: "/api/v1/asset_availability/", method: "GET", + TRes: Type>(), }, getAssetAvailability: { path: "/api/v1/asset_availability/{id}", method: "GET", + TRes: Type(), }, // Prescription endpoints