From 000138b0cf322a1f8eb5887253081769e38c787b Mon Sep 17 00:00:00 2001 From: konavivekramakrishna Date: Wed, 14 Feb 2024 10:15:30 +0530 Subject: [PATCH 01/10] Add Search Box to Resource (#7199) * add search for resource * fix styling --- src/Components/Resource/BadgesList.tsx | 1 + src/Components/Resource/Commons.tsx | 2 + src/Components/Resource/ListView.tsx | 81 ++++++++++++------- src/Components/Resource/ResourceBoard.tsx | 3 +- src/Components/Resource/ResourceBoardView.tsx | 17 +++- src/Locale/en/Resource.json | 3 +- 6 files changed, 70 insertions(+), 37 deletions(-) diff --git a/src/Components/Resource/BadgesList.tsx b/src/Components/Resource/BadgesList.tsx index 4ab4f3cc8e4..9fa1859fdd4 100644 --- a/src/Components/Resource/BadgesList.tsx +++ b/src/Components/Resource/BadgesList.tsx @@ -31,6 +31,7 @@ export default function BadgesList(props: any) { getDescShiftingFilterOrder(appliedFilters.ordering) ), badge("Status", "status"), + badge("Title", "title"), boolean("Emergency", "emergency", { trueValue: "yes", falseValue: "no", diff --git a/src/Components/Resource/Commons.tsx b/src/Components/Resource/Commons.tsx index 0162f34d02c..9ba522f763b 100644 --- a/src/Components/Resource/Commons.tsx +++ b/src/Components/Resource/Commons.tsx @@ -12,6 +12,7 @@ export const initialFilterData = { modified_date_after: null, offset: 0, ordering: null, + title: "", }; export const formatFilter = (params: any) => { @@ -35,5 +36,6 @@ export const formatFilter = (params: any) => { modified_date_before: filter.modified_date_before || undefined, modified_date_after: filter.modified_date_after || undefined, ordering: filter.ordering || undefined, + title: filter.title || undefined, }; }; diff --git a/src/Components/Resource/ListView.tsx b/src/Components/Resource/ListView.tsx index 5eb5a93fb8f..05b2ce2f4bb 100644 --- a/src/Components/Resource/ListView.tsx +++ b/src/Components/Resource/ListView.tsx @@ -14,13 +14,21 @@ import CareIcon from "../../CAREUI/icons/CareIcon"; import dayjs from "../../Utils/dayjs"; import useQuery from "../../Utils/request/useQuery"; import routes from "../../Redux/api"; +import Page from "../Common/components/Page"; +import SearchInput from "../Form/SearchInput"; const Loading = lazy(() => import("../Common/Loading")); -const PageTitle = lazy(() => import("../Common/PageTitle")); export default function ListView() { - const { qParams, Pagination, FilterBadges, advancedFilter, resultsPerPage } = - useFilters({}); + const { + qParams, + Pagination, + FilterBadges, + advancedFilter, + resultsPerPage, + updateQuery, + } = useFilters({ cacheBlacklist: ["title"] }); + const { t } = useTranslation(); const onBoardViewBtnClick = () => @@ -148,33 +156,42 @@ export default function ListView() { }; return ( -
-
- - downloadResourceRequests({ ...appliedFilters, csv: 1 }) - } - filenamePrefix="resource_requests" - /> - } - breadcrumbs={false} + downloadResourceRequests({ ...appliedFilters, csv: 1 })} + filenamePrefix="resource_requests" /> + } + breadcrumbs={false} + options={ + <> +
+ updateQuery({ [e.name]: e.value })} + placeholder={t("search_resource")} + /> +
+
+ {/* dummy div to align space as per board view */} +
+
+ + + {t("board_view")} + -
-
- - - {t("board_view")} - - - advancedFilter.setShow(true)} /> -
-
- + advancedFilter.setShow(true)} + /> +
+ + } + >
@@ -188,14 +205,16 @@ export default function ListView() { onClick={() => refetch()} > - Refresh List + {t("refresh_list")}
{data?.results && showResourceCardList(data?.results)}
- +
+ +
)}
@@ -204,6 +223,6 @@ export default function ListView() { showResourceStatus={true} key={window.location.search} /> - + ); } diff --git a/src/Components/Resource/ResourceBoard.tsx b/src/Components/Resource/ResourceBoard.tsx index d57c7a0d36f..0f16391b9ab 100644 --- a/src/Components/Resource/ResourceBoard.tsx +++ b/src/Components/Resource/ResourceBoard.tsx @@ -171,6 +171,7 @@ export default function ResourceBoard({ setIsLoading((loading) => reduceLoading("BOARD", loading)); }, [ board, + filterProp.title, filterProp.facility, filterProp.origin_facility, filterProp.approving_facility, @@ -231,7 +232,7 @@ export default function ResourceBoard({
diff --git a/src/Components/Resource/ResourceBoardView.tsx b/src/Components/Resource/ResourceBoardView.tsx index 17fb70c662f..558cd77c1f0 100644 --- a/src/Components/Resource/ResourceBoardView.tsx +++ b/src/Components/Resource/ResourceBoardView.tsx @@ -14,6 +14,7 @@ import ButtonV2 from "../Common/components/ButtonV2"; import { useTranslation } from "react-i18next"; import { AdvancedFilterButton } from "../../CAREUI/interactive/FiltersSlideover"; import CareIcon from "../../CAREUI/icons/CareIcon"; +import SearchInput from "../Form/SearchInput"; const Loading = lazy(() => import("../Common/Loading")); const PageTitle = lazy(() => import("../Common/PageTitle")); @@ -24,7 +25,10 @@ const COMPLETED = ["COMPLETED", "REJECTED"]; const ACTIVE = resourceStatusOptions.filter((o) => !COMPLETED.includes(o)); export default function BoardView() { - const { qParams, FilterBadges, advancedFilter } = useFilters({ limit: -1 }); + const { qParams, FilterBadges, advancedFilter, updateQuery } = useFilters({ + limit: -1, + cacheBlacklist: ["title"], + }); const [boardFilter, setBoardFilter] = useState(ACTIVE); // eslint-disable-next-line const [isLoading, setIsLoading] = useState(false); @@ -37,7 +41,7 @@ export default function BoardView() { }; return ( -
+
-
-
+
+ updateQuery({ [e.name]: e.value })} + placeholder={t("search_resource")} + /> Date: Wed, 14 Feb 2024 10:16:14 +0530 Subject: [PATCH 02/10] fix: hide the diagonses card if it's empty (#7196) * fix(consultation): fixes #7187 hide diagnoses card if empty * fix(consultation): resolved suggestion * Update src/Components/Facility/ConsultationDetails/index.tsx --------- Co-authored-by: Rithvik Nishad --- .../Facility/ConsultationDetails/index.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Components/Facility/ConsultationDetails/index.tsx b/src/Components/Facility/ConsultationDetails/index.tsx index 071e7bfc1af..808a2c90de9 100644 --- a/src/Components/Facility/ConsultationDetails/index.tsx +++ b/src/Components/Facility/ConsultationDetails/index.tsx @@ -401,13 +401,15 @@ export const ConsultationDetails = (props: any) => {
-
-
- + {!!consultationData.diagnoses?.length && ( +
+
+ +
-
+ )}
From 77fa4de78c1dc00a8256b007af258a7a356d9b5e Mon Sep 17 00:00:00 2001 From: Ashesh <3626859+Ashesh3@users.noreply.github.com> Date: Wed, 14 Feb 2024 10:16:41 +0530 Subject: [PATCH 03/10] Add facility name to ReportTable component (#7190) * Add facility name to ReportTable component * Refactor ReportTable component to remove facilityName prop --- .../Facility/Investigations/Reports/ReportTable.tsx | 12 ++++++++++-- .../Facility/Investigations/Reports/types.ts | 5 ++++- .../Facility/Investigations/Reports/utils.tsx | 10 +++++++--- src/Components/Patient/PatientInfoCard.tsx | 2 +- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/Components/Facility/Investigations/Reports/ReportTable.tsx b/src/Components/Facility/Investigations/Reports/ReportTable.tsx index 1f20ec94180..c15eec4e33b 100644 --- a/src/Components/Facility/Investigations/Reports/ReportTable.tsx +++ b/src/Components/Facility/Investigations/Reports/ReportTable.tsx @@ -124,9 +124,17 @@ const ReportTable: FC = ({ - {formatDateTime(session.session_created_date)} +
+ {formatDateTime(session.session_created_date)} + + {session.facility_name} + +
))} { const sessions = _.chain(data) - .map((value) => value.session_object) + .map((value) => { + return { + ...value.session_object, + facility_name: value.consultation_object?.facility_name, + facility_id: value.consultation_object?.facility, + }; + }) .uniqBy("session_external_id") .orderBy("session_created_date", "desc") .value(); @@ -28,7 +34,6 @@ export const transformData = _.memoize((data: InvestigationResponse) => { } }); const { - consultation, group, group_object, id, @@ -40,7 +45,6 @@ export const transformData = _.memoize((data: InvestigationResponse) => { } = value[0]; return { - consultation, group, group_object, id, diff --git a/src/Components/Patient/PatientInfoCard.tsx b/src/Components/Patient/PatientInfoCard.tsx index 67df8a2dd29..25683e1a461 100644 --- a/src/Components/Patient/PatientInfoCard.tsx +++ b/src/Components/Patient/PatientInfoCard.tsx @@ -411,7 +411,7 @@ export default function PatientInfoCard(props: { Principal Diagnosis:
- {principal_diagnosis.diagnosis_object.label}{" "} + {principal_diagnosis.diagnosis_object?.label ?? "-"}{" "}

From 7956c90dd4862a50071b610bc85f15e2c7cbe34a Mon Sep 17 00:00:00 2001 From: Shyam Prakash <106866225+shyamprakash123@users.noreply.github.com> Date: Wed, 14 Feb 2024 10:17:25 +0530 Subject: [PATCH 04/10] Hide Asset Type (#7180) * update * Revert "update" This reverts commit 137539925bfd73e9163e39eb5a90760bf6b24c69. * hideAssetType * update * Revert "update" This reverts commit 137539925bfd73e9163e39eb5a90760bf6b24c69. --------- Co-authored-by: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> --- cypress/e2e/assets_spec/asset_homepage.cy.ts | 2 - cypress/e2e/assets_spec/assets_creation.cy.ts | 4 - cypress/e2e/sample_test_spec/filter.cy.ts | 7 -- cypress/pageobject/Asset/AssetCreation.ts | 15 --- cypress/pageobject/Asset/AssetFilters.ts | 9 -- src/Components/Assets/AssetFilter.tsx | 16 --- src/Components/Assets/AssetManage.tsx | 5 - src/Components/Assets/AssetsList.tsx | 7 -- src/Components/Facility/AssetCreate.tsx | 101 +++++------------- 9 files changed, 28 insertions(+), 138 deletions(-) diff --git a/cypress/e2e/assets_spec/asset_homepage.cy.ts b/cypress/e2e/assets_spec/asset_homepage.cy.ts index 388f19424a4..5710df08e83 100644 --- a/cypress/e2e/assets_spec/asset_homepage.cy.ts +++ b/cypress/e2e/assets_spec/asset_homepage.cy.ts @@ -63,7 +63,6 @@ describe("Asset Tab", () => { it("Filter Asset", () => { assetFilters.filterAssets( "Dummy Facility 40", - "INTERNAL", "ACTIVE", "ONVIF Camera", "Camera Loc" @@ -71,7 +70,6 @@ describe("Asset Tab", () => { assetFilters.clickadvancefilter(); assetFilters.clickslideoverbackbutton(); // to verify the back button doesn't clear applied filters assetFilters.assertFacilityText("Dummy Facility 40"); - assetFilters.assertAssetTypeText("INTERNAL"); assetFilters.assertAssetClassText("ONVIF"); assetFilters.assertStatusText("ACTIVE"); assetFilters.assertLocationText("Camera Loc"); diff --git a/cypress/e2e/assets_spec/assets_creation.cy.ts b/cypress/e2e/assets_spec/assets_creation.cy.ts index 63f8bee50c8..f8edc2bb172 100644 --- a/cypress/e2e/assets_spec/assets_creation.cy.ts +++ b/cypress/e2e/assets_spec/assets_creation.cy.ts @@ -29,7 +29,6 @@ describe("Asset", () => { assetPage.clickCreateAsset(); assetPage.verifyEmptyAssetNameError(); - assetPage.verifyEmptyAssetTypeError(); assetPage.verifyEmptyLocationError(); assetPage.verifyEmptyStatusError(); assetPage.verifyEmptyPhoneError(); @@ -41,7 +40,6 @@ describe("Asset", () => { assetPage.createAsset(); assetPage.selectFacility("Dummy Facility 40"); assetPage.selectLocation("Camera Loc"); - assetPage.selectAssetType("Internal"); assetPage.selectAssetClass("ONVIF Camera"); const qr_id_1 = uuidv4(); @@ -68,7 +66,6 @@ describe("Asset", () => { const qr_id_2 = uuidv4(); assetPage.selectLocation("Camera Loc"); - assetPage.selectAssetType("Internal"); assetPage.selectAssetClass("ONVIF Camera"); assetPage.enterAssetDetails( "New Test Asset 2", @@ -141,7 +138,6 @@ describe("Asset", () => { assetPage.createAsset(); assetPage.selectFacility("Dummy Facility 40"); assetPage.selectLocation("Camera Loc"); - assetPage.selectAssetType("Internal"); assetPage.selectAssetClass("HL7 Vitals Monitor"); const qr_id_1 = uuidv4(); diff --git a/cypress/e2e/sample_test_spec/filter.cy.ts b/cypress/e2e/sample_test_spec/filter.cy.ts index a015d1ba7c5..df934c641bb 100644 --- a/cypress/e2e/sample_test_spec/filter.cy.ts +++ b/cypress/e2e/sample_test_spec/filter.cy.ts @@ -20,13 +20,6 @@ describe("Sample Filter", () => { .click(); }); - it("Filter by Asset Type", () => { - cy.get("#result").click(); - cy.get("li[role='option']") - .contains(/^POSITIVE$/) - .click(); - }); - it("Filter by sample type", () => { cy.get("#sample_type").click(); cy.get("li[role='option']") diff --git a/cypress/pageobject/Asset/AssetCreation.ts b/cypress/pageobject/Asset/AssetCreation.ts index 6932b5ed15e..8f611e97d92 100644 --- a/cypress/pageobject/Asset/AssetCreation.ts +++ b/cypress/pageobject/Asset/AssetCreation.ts @@ -24,14 +24,6 @@ export class AssetPage { }); } - selectAssetType(assetType: string) { - cy.get("[data-testid=asset-type-input] button") - .click() - .then(() => { - cy.get("[role='option']").contains(assetType).click(); - }); - } - selectAssetClass(assetClass: string) { cy.get("[data-testid=asset-class-input] button") .click() @@ -205,13 +197,6 @@ export class AssetPage { ); } - verifyEmptyAssetTypeError() { - cy.get("[data-testid=asset-type-input] span").should( - "contain", - "Select an asset type" - ); - } - verifyEmptyStatusError() { cy.get("[data-testid=asset-working-status-input] span").should( "contain", diff --git a/cypress/pageobject/Asset/AssetFilters.ts b/cypress/pageobject/Asset/AssetFilters.ts index 5ded59f4f63..33363f2d161 100644 --- a/cypress/pageobject/Asset/AssetFilters.ts +++ b/cypress/pageobject/Asset/AssetFilters.ts @@ -1,7 +1,6 @@ export class AssetFilters { filterAssets( facilityName: string, - assetType: string, assetStatus: string, assetClass: string, assetLocation: string @@ -13,11 +12,6 @@ export class AssetFilters { .then(() => { cy.get("[role='option']").contains(facilityName).click(); }); - cy.get("#asset-type") - .click() - .then(() => { - cy.get("[role='option']").contains(assetType).click(); - }); cy.get("#asset-status") .click() .then(() => { @@ -65,9 +59,6 @@ export class AssetFilters { assertFacilityText(text) { cy.get("[data-testid=Facility]").should("contain", text); } - assertAssetTypeText(text) { - cy.get("[data-testid='Asset Type']").should("contain", text); - } assertAssetClassText(text) { cy.get("[data-testid='Asset Class']").should("contain", text); } diff --git a/src/Components/Assets/AssetFilter.tsx b/src/Components/Assets/AssetFilter.tsx index 3edde4ab0cd..1fca1475269 100644 --- a/src/Components/Assets/AssetFilter.tsx +++ b/src/Components/Assets/AssetFilter.tsx @@ -21,9 +21,6 @@ const getDate = (value: any) => function AssetFilter(props: any) { const { filter, onChange, closeFilter, removeFilters } = props; const [facility, setFacility] = useState(null); - const [asset_type, setAssetType] = useState( - filter.asset_type ? filter.asset_type : "" - ); const [asset_status, setAssetStatus] = useState(filter.status || ""); const [asset_class, setAssetClass] = useState( filter.asset_class || "" @@ -61,7 +58,6 @@ function AssetFilter(props: any) { const applyFilter = () => { const data = { facility: facilityId, - asset_type: asset_type ?? "", asset_class: asset_class ?? "", status: asset_status ?? "", location: locationId ?? "", @@ -125,18 +121,6 @@ function AssetFilter(props: any) {

)} - o} - optionValue={(o) => o} - value={asset_type} - onChange={({ value }) => setAssetType(value)} - /> - { {asset?.description}
- {asset?.asset_type === "INTERNAL" ? ( - - ) : ( - - )} {asset?.status === "ACTIVE" ? ( ) : ( diff --git a/src/Components/Assets/AssetsList.tsx b/src/Components/Assets/AssetsList.tsx index 946618fd970..f210bf04535 100644 --- a/src/Components/Assets/AssetsList.tsx +++ b/src/Components/Assets/AssetsList.tsx @@ -45,7 +45,6 @@ const AssetsList = () => { const [isScannerActive, setIsScannerActive] = useState(false); const [totalCount, setTotalCount] = useState(0); const [facility, setFacility] = useState(); - const [asset_type, setAssetType] = useState(); const [status, setStatus] = useState(); const [asset_class, setAssetClass] = useState(); const [importAssetModalOpen, setImportAssetModalOpen] = useState(false); @@ -60,7 +59,6 @@ const AssetsList = () => { offset: (qParams.page ? qParams.page - 1 : 0) * resultsPerPage, search_text: qParams.search || "", facility: qParams.facility || "", - asset_type: qParams.asset_type || "", asset_class: qParams.asset_class || "", location: qParams.facility ? qParams.location || "" : "", status: qParams.status || "", @@ -91,10 +89,6 @@ const AssetsList = () => { prefetch: !!qParams.facility, }); - useEffect(() => { - setAssetType(qParams.asset_type); - }, [qParams.asset_type]); - useEffect(() => { setStatus(qParams.status); }, [qParams.status]); @@ -387,7 +381,6 @@ const AssetsList = () => { qParams.facility && facilityObject?.name ), badge("Name/Serial No./QR ID", "search"), - value("Asset Type", "asset_type", asset_type ?? ""), value("Asset Class", "asset_class", asset_class ?? ""), value("Status", "status", status?.replace(/_/g, " ") ?? ""), value( diff --git a/src/Components/Facility/AssetCreate.tsx b/src/Components/Facility/AssetCreate.tsx index 784174cd2f7..0c422d1f646 100644 --- a/src/Components/Facility/AssetCreate.tsx +++ b/src/Components/Facility/AssetCreate.tsx @@ -40,7 +40,6 @@ const Loading = lazy(() => import("../Common/Loading")); const formErrorKeys = [ "name", - "asset_type", "asset_class", "description", "is_working", @@ -103,12 +102,10 @@ const AssetCreate = (props: AssetProps) => { const { goBack } = useAppHistory(); const { facilityId, assetId } = props; - let assetTypeInitial: AssetType; let assetClassInitial: AssetClass; const [state, dispatch] = useReducer(asset_create_reducer, initialState); const [name, setName] = useState(""); - const [asset_type, setAssetType] = useState(); const [asset_class, setAssetClass] = useState(); const [not_working_reason, setNotWorkingReason] = useState(""); const [description, setDescription] = useState(""); @@ -177,7 +174,6 @@ const AssetCreate = (props: AssetProps) => { setName(asset.name); setDescription(asset.description); setLocation(asset.location_object.id!); - setAssetType(asset.asset_type); setAssetClass(asset.asset_class); setIsWorking(String(asset.is_working)); setNotWorkingReason(asset.not_working_reason); @@ -219,12 +215,6 @@ const AssetCreate = (props: AssetProps) => { invalidForm = true; } return; - case "asset_type": - if (!asset_type || asset_type == "NONE") { - errors[field] = "Select an asset type"; - invalidForm = true; - } - return; case "support_phone": { if (!support_phone) { errors[field] = "Field is required"; @@ -282,7 +272,6 @@ const AssetCreate = (props: AssetProps) => { setName(""); setDescription(""); setLocation(""); - setAssetType(assetTypeInitial); setAssetClass(assetClassInitial); setIsWorking(undefined); setNotWorkingReason(""); @@ -307,7 +296,7 @@ const AssetCreate = (props: AssetProps) => { setIsLoading(true); const data: any = { name: name, - asset_type: asset_type, + asset_type: AssetType.INTERNAL, asset_class: asset_class || "", description: description, is_working: is_working, @@ -547,68 +536,34 @@ const AssetCreate = (props: AssetProps) => { errors={state.errors.location} />
- {/* Asset Type */} -
-
- title} - optionDescription={({ description }) => description} - optionValue={({ value }) => value} - onChange={({ value }) => setAssetType(value)} - error={state.errors.asset_type} - /> -
- {/* Asset Class */} -
- title} - optionValue={({ value }) => value} - onChange={({ value }) => setAssetClass(value)} - error={state.errors.asset_class} - /> -
+ {/* Asset Class */} +
+ title} + optionValue={({ value }) => value} + onChange={({ value }) => setAssetClass(value)} + error={state.errors.asset_class} + />
{/* Description */}
Date: Wed, 14 Feb 2024 10:17:54 +0530 Subject: [PATCH 05/10] Increase the Add button height in skills slideover. (#7163) * Fixed btn height * updated height, width, font-size according to the requested changes. * update * Revert "update" This reverts commit 137539925bfd73e9163e39eb5a90760bf6b24c69. --- src/Components/Users/ManageUsers.tsx | 2 +- src/Components/Users/SkillsSlideOver.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Components/Users/ManageUsers.tsx b/src/Components/Users/ManageUsers.tsx index 6f5de125600..15f4ba4ed81 100644 --- a/src/Components/Users/ManageUsers.tsx +++ b/src/Components/Users/ManageUsers.tsx @@ -671,7 +671,7 @@ function UserFacilities(props: { user: any }) { addFacility(username, facility)} > Add diff --git a/src/Components/Users/SkillsSlideOver.tsx b/src/Components/Users/SkillsSlideOver.tsx index 63353479f0d..616dbb6404d 100644 --- a/src/Components/Users/SkillsSlideOver.tsx +++ b/src/Components/Users/SkillsSlideOver.tsx @@ -125,7 +125,7 @@ export default ({ show, setShow, username }: IProps) => { id="add-skill-button" disabled={!authorizeForAddSkill} onClick={() => addSkill(username, selectedSkill)} - className="w-6rem" + className="mt-1 h-[45px] w-[74px] text-base" > {t("add")} From bba3b5c7d2172ff01cc481d8f75d18df6403f12d Mon Sep 17 00:00:00 2001 From: Ashesh <3626859+Ashesh3@users.noreply.github.com> Date: Wed, 14 Feb 2024 10:18:25 +0530 Subject: [PATCH 06/10] Set Form Drafts to expire after 24 hours (#7125) --- src/Utils/AutoSave.tsx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Utils/AutoSave.tsx b/src/Utils/AutoSave.tsx index 5cdf118650f..0c929f371e5 100644 --- a/src/Utils/AutoSave.tsx +++ b/src/Utils/AutoSave.tsx @@ -104,6 +104,23 @@ export function DraftSection(props: { }; }, []); + // Remove drafts older than 24 hours + useEffect(() => { + const keys = Object.keys(localStorage); + const now = Date.now(); + keys.forEach((key) => { + if (key.startsWith("form_draft_")) { + const savedDrafts = localStorage.getItem(key); + const drafts = savedDrafts ? JSON.parse(savedDrafts) : []; + const newDrafts = drafts.filter( + (draft: Draft) => now - draft.timestamp < 24 * 60 * 60 * 1000 + ); + localStorage.setItem(key, JSON.stringify(newDrafts)); + if (newDrafts.length === 0) localStorage.removeItem(key); + } + }); + }, []); + return ( <> {drafts && ( From 2cc66f08e2f49d9dadf21fd038e724e9bfadbd5d Mon Sep 17 00:00:00 2001 From: Ashesh <3626859+Ashesh3@users.noreply.github.com> Date: Wed, 14 Feb 2024 12:51:53 +0530 Subject: [PATCH 07/10] Update Uptime endpoint for AssetUptime (#7210) * Track uptime for Locations * Refactor Uptime component to accept route and params * Remove unused import in api.tsx --- src/Components/Assets/AssetManage.tsx | 7 ++++- src/Components/Assets/AssetTypes.tsx | 11 ++----- src/Components/Common/Uptime.tsx | 41 ++++++++++++++------------- src/Redux/api.tsx | 25 +++++++--------- 4 files changed, 41 insertions(+), 43 deletions(-) diff --git a/src/Components/Assets/AssetManage.tsx b/src/Components/Assets/AssetManage.tsx index 0da432eccb6..77bb88da3a8 100644 --- a/src/Components/Assets/AssetManage.tsx +++ b/src/Components/Assets/AssetManage.tsx @@ -498,7 +498,12 @@ const AssetManage = (props: AssetManageProps) => {
{asset?.id && asset?.asset_class && - asset?.asset_class != AssetClass.NONE && } + asset?.asset_class != AssetClass.NONE && ( + + )}
Service History
>; + params?: Record; + }> +) { const [summary, setSummary] = useState<{ - [key: number]: AssetUptimeRecord[]; + [key: number]: AvailabilityRecord[]; }>([]); - const { data, loading } = useQuery(routes.listAssetAvailability, { - query: { external_id: props.assetId }, + const { data, loading } = useQuery(props.route, { + pathParams: props.params, onResponse: ({ data }) => setUptimeRecord(data?.results.reverse() ?? []), }); const availabilityData = data?.results ?? []; @@ -186,8 +191,8 @@ export default function Uptime(props: { assetId: string }) { setNumDays(Math.min(newNumDays, 100)); }; - const setUptimeRecord = (records: AssetUptimeRecord[]): void => { - const recordsByDayBefore: { [key: number]: AssetUptimeRecord[] } = {}; + const setUptimeRecord = (records: AvailabilityRecord[]): void => { + const recordsByDayBefore: { [key: number]: AvailabilityRecord[] } = {}; records.forEach((record) => { const timestamp = dayjs(record.timestamp).startOf("day"); @@ -207,10 +212,8 @@ export default function Uptime(props: { assetId: string }) { recordsByDayBefore[i] = []; if (statusToCarryOver) { recordsByDayBefore[i].push({ - id: "", - asset: { id: "", name: "" }, - created_date: "", - modified_date: "", + linked_id: "", + linked_model: "", status: statusToCarryOver, timestamp: dayjs() .subtract(i, "days") @@ -225,10 +228,8 @@ export default function Uptime(props: { assetId: string }) { ).length === 0 ) { recordsByDayBefore[i].unshift({ - id: "", - asset: { id: "", name: "" }, - created_date: "", - modified_date: "", + linked_id: "", + linked_model: "", status: statusToCarryOver, timestamp: dayjs() .subtract(i, "days") @@ -284,7 +285,7 @@ export default function Uptime(props: { assetId: string }) { const statusColors: (typeof STATUS_COLORS)[keyof typeof STATUS_COLORS][] = []; let dayUptimeScore = 0; - const recordsInPeriodCache: { [key: number]: AssetUptimeRecord[] } = {}; + const recordsInPeriodCache: { [key: number]: AvailabilityRecord[] } = {}; for (let i = 0; i < 3; i++) { const start = i * 8; const end = (i + 1) * 8; diff --git a/src/Redux/api.tsx b/src/Redux/api.tsx index eed17ad3b4b..40c842adc07 100644 --- a/src/Redux/api.tsx +++ b/src/Redux/api.tsx @@ -27,7 +27,7 @@ import { AssetService, AssetServiceUpdate, AssetTransaction, - AssetUptimeRecord, + AvailabilityRecord, PatientAssetBed, } from "../Components/Assets/AssetTypes"; import { @@ -371,6 +371,11 @@ const routes = { path: "/api/v1/facility/{facility_external_id}/asset_location/{external_id}/", method: "PATCH", }, + getFacilityAssetLocationAvailability: { + path: "/api/v1/facility/{facility_external_id}/asset_location/{external_id}/availability/", + method: "GET", + TRes: Type>(), + }, // Asset bed listAssetBeds: { @@ -1116,6 +1121,11 @@ const routes = { TRes: Type(), TBody: Type>(), }, + listAssetAvailability: { + path: "/api/v1/asset/{external_id}/availability/", + method: "GET", + TRes: Type>(), + }, // Asset transaction endpoints @@ -1290,19 +1300,6 @@ const routes = { }, }, - // Asset Availability endpoints - - listAssetAvailability: { - path: "/api/v1/asset_availability/", - method: "GET", - TRes: Type>(), - }, - getAssetAvailability: { - path: "/api/v1/asset_availability/{id}", - method: "GET", - TRes: Type(), - }, - // Prescription endpoints listPrescriptions: { From 5e0727d88f2801c059d051a80d9ed25f124f6606 Mon Sep 17 00:00:00 2001 From: Kshitij Verma <101321276+kshitijv256@users.noreply.github.com> Date: Wed, 14 Feb 2024 12:54:23 +0530 Subject: [PATCH 08/10] Added support for multi-line text input for Doctor Notes (#6977) * Changed TextFormField to TextAreaFormField * made doctor notes input size dynamic * fixed max height of textareafield * made max height variable * replaced ids with ref * removed id prop * added required comments * added required comments * lineheight computed dynamically --- .../ConsultationDoctorNotes/index.tsx | 8 +-- .../Facility/PatientNotesSlideover.tsx | 7 +-- .../AutoExpandingTextInputFormField.tsx | 30 +++++++++++ .../Form/FormFields/TextAreaFormField.tsx | 53 +++++++++++-------- 4 files changed, 71 insertions(+), 27 deletions(-) create mode 100644 src/Components/Form/FormFields/AutoExpandingTextInputFormField.tsx diff --git a/src/Components/Facility/ConsultationDoctorNotes/index.tsx b/src/Components/Facility/ConsultationDoctorNotes/index.tsx index 8e39ee04e4e..c17ee3fb2db 100644 --- a/src/Components/Facility/ConsultationDoctorNotes/index.tsx +++ b/src/Components/Facility/ConsultationDoctorNotes/index.tsx @@ -1,7 +1,6 @@ import { useState } from "react"; import * as Notification from "../../../Utils/Notifications.js"; import Page from "../../Common/components/Page"; -import TextFormField from "../../Form/FormFields/TextFormField"; import ButtonV2 from "../../Common/components/ButtonV2"; import CareIcon from "../../../CAREUI/icons/CareIcon"; import { NonReadOnlyUsers } from "../../../Utils/AuthorizeFor"; @@ -13,6 +12,7 @@ import request from "../../../Utils/request/request.js"; import useQuery from "../../../Utils/request/useQuery.js"; import useKeyboardShortcut from "use-keyboard-shortcut"; import { isAppleDevice } from "../../../Utils/utils.js"; +import AutoExpandingTextInputFormField from "../../Form/FormFields/AutoExpandingTextInputFormField.js"; interface ConsultationDoctorNotesProps { patientId: string; @@ -120,12 +120,14 @@ const ConsultationDoctorNotes = (props: ConsultationDoctorNotesProps) => { />
- setNoteField(e.value)} className="grow" - type="text" errorClassName="hidden" placeholder="Type your Note" disabled={!patientActive} diff --git a/src/Components/Facility/PatientNotesSlideover.tsx b/src/Components/Facility/PatientNotesSlideover.tsx index 5ecf30cfcdf..2e231576eb2 100644 --- a/src/Components/Facility/PatientNotesSlideover.tsx +++ b/src/Components/Facility/PatientNotesSlideover.tsx @@ -3,7 +3,6 @@ import * as Notification from "../../Utils/Notifications.js"; import { NonReadOnlyUsers } from "../../Utils/AuthorizeFor"; import CareIcon from "../../CAREUI/icons/CareIcon"; import { classNames, isAppleDevice } from "../../Utils/utils"; -import TextFormField from "../Form/FormFields/TextFormField"; import ButtonV2 from "../Common/components/ButtonV2"; import { make as Link } from "../Common/components/Link.bs"; import { useMessageListener } from "../../Common/hooks/useMessageListener"; @@ -12,6 +11,7 @@ import request from "../../Utils/request/request"; import routes from "../../Redux/api"; import { PatientNoteStateType } from "./models"; import useKeyboardShortcut from "use-keyboard-shortcut"; +import AutoExpandingTextInputFormField from "../Form/FormFields/AutoExpandingTextInputFormField.js"; interface PatientNotesProps { patientId: string; @@ -169,13 +169,14 @@ export default function PatientNotesSlideover(props: PatientNotesProps) { setReload={setReload} />
- setNoteField(e.value)} className="grow" - type="text" errorClassName="hidden" placeholder="Type your Note" disabled={!patientActive} diff --git a/src/Components/Form/FormFields/AutoExpandingTextInputFormField.tsx b/src/Components/Form/FormFields/AutoExpandingTextInputFormField.tsx new file mode 100644 index 00000000000..22707f133bc --- /dev/null +++ b/src/Components/Form/FormFields/AutoExpandingTextInputFormField.tsx @@ -0,0 +1,30 @@ +import React, { useEffect, useRef } from "react"; +import TextAreaFormField, { TextAreaFormFieldProps } from "./TextAreaFormField"; + +type AutoExpandingTextInputFormFieldProps = TextAreaFormFieldProps & { + maxHeight?: number; +}; + +const AutoExpandingTextInputFormField = ( + props: AutoExpandingTextInputFormFieldProps +) => { + const myref = useRef(null); + useEffect(() => { + if (myref.current == null) return; + const text = myref.current.textContent?.split("\n"); + const len = text?.length || 1; + // 46 is height of the textarea when there is only 1 line + // getting line height from window + const lineHeight = + window.getComputedStyle(myref.current).lineHeight.slice(0, -2) || "20"; + // added 26 for padding (20+26 = 46) + const height = + Math.min(len * parseInt(lineHeight), (props.maxHeight || 160) - 26) + 26; + // 160 is the max height of the textarea if not specified + myref.current.style.cssText = "height:" + height + "px"; + }); + + return ; +}; + +export default AutoExpandingTextInputFormField; diff --git a/src/Components/Form/FormFields/TextAreaFormField.tsx b/src/Components/Form/FormFields/TextAreaFormField.tsx index 23a7d025938..5c23bfec764 100644 --- a/src/Components/Form/FormFields/TextAreaFormField.tsx +++ b/src/Components/Form/FormFields/TextAreaFormField.tsx @@ -1,33 +1,44 @@ +import { forwardRef } from "react"; import FormField from "./FormField"; import { FormFieldBaseProps, useFormFieldPropsResolver } from "./Utils"; -type TextAreaFormFieldProps = FormFieldBaseProps & { +export type TextAreaFormFieldProps = FormFieldBaseProps & { placeholder?: string; value?: string | number; rows?: number; // prefixIcon?: React.ReactNode; // suffixIcon?: React.ReactNode; + onFocus?: (event: React.FocusEvent) => void; + onBlur?: (event: React.FocusEvent) => void; }; -const TextAreaFormField = ({ rows = 3, ...props }: TextAreaFormFieldProps) => { - const field = useFormFieldPropsResolver(props as any); - return ( - - +
+ { + setIsEditing(false); + setNoteField(note.note); + }} + id="cancel-update-note-button" + > + + Cancel + + + + Update Note + +
+
+ ) : ( +
{noteField}
+ )} +
+ }
-
+ {showEditHistory && ( + setShowEditHistory(false)} + title={t("edit_history")} + > +
+
+

+ Edit History for note + {note.id} +

+
+
+ {editHistory.length === 0 && ( +
+ +
+ )} + {editHistory?.map((edit, index) => { + const isLast = index === editHistory.length - 1; + return ( +
+
+
+

+ {isLast ? "Created" : "Edited"} On +

+

+ {formatDateTime(edit.edited_date)} +

+
+
+
+

Note

+

{edit.note}

+
+
+ ); + })} +
+
+ { + setShowEditHistory(false); + }} + > + {t("close")} + +
+
+
+ )} + ); }; diff --git a/src/Components/Facility/PatientNotesList.tsx b/src/Components/Facility/PatientNotesList.tsx index 96f9dcad871..a36762072b9 100644 --- a/src/Components/Facility/PatientNotesList.tsx +++ b/src/Components/Facility/PatientNotesList.tsx @@ -74,7 +74,9 @@ const PatientNotesList = (props: PatientNotesProps) => { ); } - return ; + return ( + + ); }; export default PatientNotesList; diff --git a/src/Components/Facility/PatientNotesSlideover.tsx b/src/Components/Facility/PatientNotesSlideover.tsx index 2e231576eb2..8943d7fe21a 100644 --- a/src/Components/Facility/PatientNotesSlideover.tsx +++ b/src/Components/Facility/PatientNotesSlideover.tsx @@ -30,6 +30,8 @@ export default function PatientNotesSlideover(props: PatientNotesProps) { notes: [], cPage: 1, totalPages: 1, + patientId: props.patientId, + facilityId: props.facilityId, }; const [state, setState] = useState(initialData); @@ -163,10 +165,9 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
& { leadingPadding?: string | undefined; min?: string | number; max?: string | number; + onKeyDown?: (event: React.KeyboardEvent) => void; onFocus?: (event: React.FocusEvent) => void; onBlur?: (event: React.FocusEvent) => void; }; @@ -62,6 +63,7 @@ const TextFormField = forwardRef((props: TextFormFieldProps, ref) => { onFocus={props.onFocus} onBlur={props.onBlur} onChange={(e) => field.handleChange(e.target.value)} + onKeyDown={props.onKeyDown} /> ); diff --git a/src/Redux/api.tsx b/src/Redux/api.tsx index 40c842adc07..4893bfbd33f 100644 --- a/src/Redux/api.tsx +++ b/src/Redux/api.tsx @@ -50,6 +50,7 @@ import { WardModel, LocationModel, PatientNotesModel, + PatientNotesEditModel, BedModel, MinimumQuantityItemResponse, InventorySummaryResponse, @@ -677,6 +678,16 @@ const routes = { method: "POST", TRes: Type(), }, + updatePatientNote: { + path: "/api/v1/patient/{patientId}/notes/{noteId}/", + method: "PUT", + TRes: Type(), + }, + getPatientNoteEditHistory: { + path: "/api/v1/patient/{patientId}/notes/{noteId}/edits/", + method: "GET", + TRes: Type>(), + }, sampleTestList: { path: "/api/v1/patient/{patientId}/test_sample/", }, From d36c0f24a60e09adaee68bc74b0ebc04dda6967f Mon Sep 17 00:00:00 2001 From: konavivekramakrishna Date: Wed, 14 Feb 2024 13:48:40 +0530 Subject: [PATCH 10/10] Replace useDispatch in Patient Files (src/Components/Patient/) (#7078) * replaced useDispatch in patientHome * replace usedispatch in patientfiler and managepatinet * add patientfilter * replace useDispatch in dailyroundslistdetials * replaced useDispatch in sampleDetails * replace useDispatch in sampleFilters * replace useDispatch in samplePreview * sampleTestCard * replace useDispatch in sampleTest * replace useDispatch in sampleViewAdmin * replace useDispatch in shiftCreate * fix * fix * revert managePatients and patientFilter useDispatch * replace useDispatch in managePatients * fix * fix * replace useDispatch in PatientFilter * fix prefetch * minor fix * add trailing slashes to api's * fix based on review * Update package-lock.json * Update package-lock.json * replace reload * implement paginated list * fix types * rm Timeline from paginatedList * Update button styling in CommentsSection component * Fix API paths in Redux file * Update API paths * remove unused actions * fix eslint * fix daily rounds and filters * fix sample view admin * fix shifting * fix based on review * minor fix * fix lint --------- Co-authored-by: rithviknishad Co-authored-by: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> --- src/CAREUI/display/Timeline.tsx | 2 +- src/CAREUI/misc/PaginatedList.tsx | 29 +- .../Consultations/DailyRoundsList.tsx | 95 ++-- .../Patient/DailyRoundListDetails.tsx | 78 ++-- src/Components/Patient/ManagePatients.tsx | 229 +++------- src/Components/Patient/PatientHome.tsx | 422 ++++++------------ src/Components/Patient/SampleDetails.tsx | 91 ++-- src/Components/Patient/SampleFilters.tsx | 32 +- src/Components/Patient/SamplePreview.tsx | 41 +- src/Components/Patient/SampleTest.tsx | 61 ++- src/Components/Patient/SampleTestCard.tsx | 33 +- src/Components/Patient/SampleViewAdmin.tsx | 133 +++--- src/Components/Patient/ShiftCreate.tsx | 76 ++-- src/Redux/actions.tsx | 63 +-- src/Redux/api.tsx | 39 +- 15 files changed, 540 insertions(+), 884 deletions(-) diff --git a/src/CAREUI/display/Timeline.tsx b/src/CAREUI/display/Timeline.tsx index 276c437056c..49ace78bd88 100644 --- a/src/CAREUI/display/Timeline.tsx +++ b/src/CAREUI/display/Timeline.tsx @@ -14,7 +14,7 @@ export interface TimelineEvent { } interface TimelineProps { - className: string; + className?: string; children: React.ReactNode | React.ReactNode[]; name: string; } diff --git a/src/CAREUI/misc/PaginatedList.tsx b/src/CAREUI/misc/PaginatedList.tsx index 1487d69e4fa..363e657f253 100644 --- a/src/CAREUI/misc/PaginatedList.tsx +++ b/src/CAREUI/misc/PaginatedList.tsx @@ -7,7 +7,6 @@ import ButtonV2, { import CareIcon from "../icons/CareIcon"; import { classNames } from "../../Utils/utils"; import Pagination from "../../Components/Common/Pagination"; -import Timeline from "../display/Timeline"; const DEFAULT_PER_PAGE_LIMIT = 14; @@ -135,21 +134,19 @@ const Items = (props: ItemsProps) => { } return ( - -
    - {loading && props.shimmer - ? Array.from({ length: props.shimmerCount ?? 8 }).map((_, i) => ( -
  • - {props.shimmer} -
  • - )) - : items.map((item, index, items) => ( -
  • - {props.children(item, items)} -
  • - ))} -
-
+
    + {loading && props.shimmer + ? Array.from({ length: props.shimmerCount ?? 8 }).map((_, i) => ( +
  • + {props.shimmer} +
  • + )) + : items.map((item, index, items) => ( +
  • + {props.children(item, items)} +
  • + ))} +
); }; diff --git a/src/Components/Facility/Consultations/DailyRoundsList.tsx b/src/Components/Facility/Consultations/DailyRoundsList.tsx index d438ee098c7..0d569eade41 100644 --- a/src/Components/Facility/Consultations/DailyRoundsList.tsx +++ b/src/Components/Facility/Consultations/DailyRoundsList.tsx @@ -10,7 +10,8 @@ import PageTitle from "../../Common/PageTitle"; import DailyRoundsFilter from "./DailyRoundsFilter"; import { ConsultationModel } from "../models"; import { useSlugs } from "../../../Common/hooks/useSlug"; -import { TimelineNode } from "../../../CAREUI/display/Timeline"; + +import Timeline, { TimelineNode } from "../../../CAREUI/display/Timeline"; import { useState } from "react"; import { QueryParams } from "../../../Utils/request/types"; @@ -52,69 +53,71 @@ export default function DailyRoundsList({ consultation }: Props) { - className="flex grow flex-col gap-3"> - {(item, items) => { - if (item.rounds_type === "AUTOMATED") { + + className="flex grow flex-col gap-3 rounded-lg bg-white p-2 shadow"> + {(item, items) => { + if (item.rounds_type === "AUTOMATED") { + return ( + + + + ); + } + + const itemUrl = ["NORMAL", "TELEMEDICINE"].includes( + item.rounds_type as string + ) + ? `${consultationUrl}/daily-rounds/${item.id}` + : `${consultationUrl}/daily_rounds/${item.id}`; + return ( - navigate(itemUrl)} + onUpdateLog={() => navigate(`${itemUrl}/update`)} /> ); - } - - const itemUrl = ["NORMAL", "TELEMEDICINE"].includes( - item.rounds_type - ) - ? `${consultationUrl}/daily-rounds/${item.id}` - : `${consultationUrl}/daily_rounds/${item.id}`; - - return ( - - navigate(itemUrl)} - onUpdateLog={() => navigate(`${itemUrl}/update`)} - /> - - ); - }} - + }} + +
diff --git a/src/Components/Patient/DailyRoundListDetails.tsx b/src/Components/Patient/DailyRoundListDetails.tsx index 8f313c0a51d..02ad9aa47fa 100644 --- a/src/Components/Patient/DailyRoundListDetails.tsx +++ b/src/Components/Patient/DailyRoundListDetails.tsx @@ -1,75 +1,53 @@ -import { lazy, useCallback, useState } from "react"; -import { useDispatch } from "react-redux"; +import { lazy, useState } from "react"; import { CONSCIOUSNESS_LEVEL, CURRENT_HEALTH_CHANGE, SYMPTOM_CHOICES, } from "../../Common/constants"; -import { statusType, useAbortableEffect } from "../../Common/utils"; -import { getConsultationDailyRoundsDetails } from "../../Redux/actions"; import { DailyRoundsModel } from "./models"; import Page from "../Common/components/Page"; import ButtonV2 from "../Common/components/ButtonV2"; import { formatDateTime } from "../../Utils/utils"; +import useQuery from "../../Utils/request/useQuery"; +import routes from "../../Redux/api"; const Loading = lazy(() => import("../Common/Loading")); const symptomChoices = [...SYMPTOM_CHOICES]; const currentHealthChoices = [...CURRENT_HEALTH_CHANGE]; export const DailyRoundListDetails = (props: any) => { const { facilityId, patientId, consultationId, id } = props; - const dispatch: any = useDispatch(); const [dailyRoundListDetailsData, setDailyRoundListDetails] = useState({}); - const [isLoading, setIsLoading] = useState(false); - const fetchpatient = useCallback( - async (status: statusType) => { - setIsLoading(true); - const res = await dispatch( - getConsultationDailyRoundsDetails({ consultationId, id }) - ); - if (!status.aborted) { - if (res && res.data) { - const currentHealth = currentHealthChoices.find( - (i) => i.text === res.data.current_health - ); + const { loading: isLoading } = useQuery(routes.getDailyReport, { + pathParams: { consultationId, id }, + onResponse: ({ res, data }) => { + if (res && data) { + const currentHealth = currentHealthChoices.find( + (i) => i.text === data.current_health + ); - const data: DailyRoundsModel = { - ...res.data, - temperature: Number(res.data.temperature) - ? res.data.temperature - : "", - additional_symptoms_text: "", - medication_given: - Object.keys(res.data.medication_given).length === 0 - ? [] - : res.data.medication_given, - current_health: currentHealth - ? currentHealth.desc - : res.data.current_health, - }; - if (res.data.additional_symptoms?.length) { - const symptoms = res.data.additional_symptoms.map( - (symptom: number) => { - const option = symptomChoices.find((i) => i.id === symptom); - return option ? option.text.toLowerCase() : symptom; - } - ); - data.additional_symptoms_text = symptoms.join(", "); - } - setDailyRoundListDetails(data); + const tdata: DailyRoundsModel = { + ...data, + temperature: Number(data.temperature) ? data.temperature : "", + additional_symptoms_text: "", + medication_given: data.medication_given ?? [], + + current_health: currentHealth + ? currentHealth.desc + : data.current_health, + }; + if (data.additional_symptoms?.length) { + const symptoms = data.additional_symptoms.map((symptom: number) => { + const option = symptomChoices.find((i) => i.id === symptom); + return option ? option.text.toLowerCase() : symptom; + }); + tdata.additional_symptoms_text = symptoms.join(", "); } - setIsLoading(false); + setDailyRoundListDetails(tdata); } }, - [consultationId, dispatch, id] - ); - useAbortableEffect( - (status: statusType) => { - fetchpatient(status); - }, - [dispatch, fetchpatient] - ); + }); if (isLoading) { return ; diff --git a/src/Components/Patient/ManagePatients.tsx b/src/Components/Patient/ManagePatients.tsx index ce8475e4c66..5e8afaf2d5c 100644 --- a/src/Components/Patient/ManagePatients.tsx +++ b/src/Components/Patient/ManagePatients.tsx @@ -11,19 +11,9 @@ import { } from "../../Common/constants"; import { FacilityModel, PatientCategory } from "../Facility/models"; import { Link, navigate } from "raviger"; -import { ReactNode, lazy, useCallback, useEffect, useState } from "react"; -import { - getAllPatient, - getAnyFacility, - getDistrict, - getFacilityAssetLocation, - getLocalBody, -} from "../../Redux/actions"; -import { - statusType, - useAbortableEffect, - parseOptionId, -} from "../../Common/utils"; +import { ReactNode, lazy, useEffect, useState } from "react"; +import { getAllPatient } from "../../Redux/actions"; +import { parseOptionId } from "../../Common/utils"; import { AdvancedFilterButton } from "../../CAREUI/interactive/FiltersSlideover"; import ButtonV2 from "../Common/components/ButtonV2"; @@ -42,7 +32,6 @@ import SearchInput from "../Form/SearchInput"; import SortDropdownMenu from "../Common/SortDropdown"; import SwitchTabs from "../Common/components/SwitchTabs"; import { formatAge, parsePhoneNumber } from "../../Utils/utils.js"; -import { useDispatch } from "react-redux"; import useFilters from "../../Common/hooks/useFilters"; import { useTranslation } from "react-i18next"; import Page from "../Common/components/Page.js"; @@ -93,10 +82,6 @@ const PatientCategoryDisplayText: Record = { export const PatientManager = () => { const { t } = useTranslation(); - const dispatch: any = useDispatch(); - const [data, setData] = useState(); - const [isLoading, setIsLoading] = useState(false); - const [totalCount, setTotalCount] = useState(0); const { qParams, updateQuery, @@ -121,10 +106,6 @@ export const PatientManager = () => { const [showDialog, setShowDialog] = useState(false); const [showDoctors, setShowDoctors] = useState(false); const [showDoctorConnect, setShowDoctorConnect] = useState(false); - const [districtName, setDistrictName] = useState(""); - const [localbodyName, setLocalbodyName] = useState(""); - const [facilityBadgeName, setFacilityBadge] = useState(""); - const [locationBadgeName, setLocationBadge] = useState(""); const [phone_number, setPhoneNumber] = useState(""); const [phoneNumberError, setPhoneNumberError] = useState(""); const [emergency_phone_number, setEmergencyPhoneNumber] = useState(""); @@ -367,73 +348,17 @@ export const PatientManager = () => { return cleanedData; }; - useEffect(() => { - setIsLoading(true); - if (!params.phone_number) { - setPhoneNumber("+91"); - } - if (!params.emergency_phone_number) { - setEmergencyPhoneNumber("+91"); - } - dispatch(getAllPatient(params, "listPatients")).then((res: any) => { - if (res && res.data) { - setData(res.data.results); - setTotalCount(res.data.count); - setIsLoading(false); + const { loading: isLoading, data } = useQuery(routes.patientList, { + query: params, + onResponse: () => { + if (!params.phone_number) { + setPhoneNumber("+91"); } - }); - }, [ - dispatch, - qParams.last_consultation_medico_legal_case, - qParams.last_consultation_encounter_date_before, - qParams.last_consultation_encounter_date_after, - qParams.last_consultation_discharge_date_before, - qParams.last_consultation_discharge_date_after, - qParams.age_max, - qParams.age_min, - qParams.last_consultation_admitted_bed_type_list, - qParams.last_consultation__new_discharge_reason, - qParams.last_consultation_current_bed__location, - qParams.facility, - qParams.facility_type, - qParams.district, - qParams.category, - qParams.gender, - qParams.ordering, - qParams.created_date_before, - qParams.created_date_after, - qParams.modified_date_before, - qParams.modified_date_after, - qParams.is_active, - qParams.disease_status, - qParams.name, - qParams.patient_no, - qParams.page, - qParams.phone_number, - qParams.emergency_phone_number, - qParams.srf_id, - qParams.covin_id, - qParams.number_of_doses, - qParams.lsgBody, - qParams.is_kasp, - qParams.is_declared_positive, - qParams.date_declared_positive_before, - qParams.date_declared_positive_after, - qParams.date_of_result_before, - qParams.date_of_result_after, - qParams.last_consultation_symptoms_onset_date_before, - qParams.last_consultation_symptoms_onset_date_after, - qParams.last_vaccinated_date_before, - qParams.last_vaccinated_date_after, - qParams.last_consultation_is_telemedicine, - qParams.is_antenatal, - qParams.ventilator_interface, - qParams.diagnoses, - qParams.diagnoses_confirmed, - qParams.diagnoses_provisional, - qParams.diagnoses_unconfirmed, - qParams.diagnoses_differential, - ]); + if (!params.emergency_phone_number) { + setEmergencyPhoneNumber("+91"); + } + }, + }); const getTheCategoryFromId = () => { let category_name; @@ -448,80 +373,35 @@ export const PatientManager = () => { } }; - const fetchDistrictName = useCallback( - async (status: statusType) => { - const res = - Number(qParams.district) && - (await dispatch(getDistrict(qParams.district))); - if (!status.aborted) { - setDistrictName(res?.data?.name); - } - }, - [dispatch, qParams.district] - ); - - useAbortableEffect( - (status: statusType) => { - fetchDistrictName(status); - }, - [fetchDistrictName] - ); - - const fetchLocalbodyName = useCallback( - async (status: statusType) => { - const res = - Number(qParams.lsgBody) && - (await dispatch(getLocalBody({ id: qParams.lsgBody }))); - if (!status.aborted) { - setLocalbodyName(res?.data?.name); - } - }, - [dispatch, qParams.lsgBody] - ); - - useAbortableEffect( - (status: statusType) => { - fetchLocalbodyName(status); + const { data: districtData } = useQuery(routes.getDistrict, { + pathParams: { + id: qParams.district, }, - [fetchLocalbodyName] - ); - - const fetchFacilityBadgeName = useCallback( - async (status: statusType) => { - const res = - qParams.facility && (await dispatch(getAnyFacility(qParams.facility))); + prefetch: !!Number(qParams.district), + }); - if (!status.aborted) { - setFacilityBadge(res?.data?.name); - } + const { data: LocalBodyData } = useQuery(routes.getLocalBody, { + pathParams: { + id: qParams.lsgBody, }, - [dispatch, qParams.facility] - ); - - const fetchLocationBadgeName = useCallback( - async (status: statusType) => { - const res = - qParams.last_consultation_current_bed__location && - (await dispatch( - getFacilityAssetLocation( - qParams.facility, - qParams.last_consultation_current_bed__location - ) - )); - - if (!status.aborted) { - setLocationBadge(res?.data?.name); - } - }, - [dispatch, qParams.last_consultation_current_bed__location] - ); + prefetch: !!Number(qParams.lsgBody), + }); - useAbortableEffect( - (status: statusType) => { - fetchFacilityBadgeName(status); - fetchLocationBadgeName(status); + const { data: facilityData } = useQuery(routes.getAnyFacility, { + pathParams: { + id: qParams.facility, }, - [fetchFacilityBadgeName, fetchLocationBadgeName] + prefetch: !!qParams.facility, + }); + const { data: facilityAssetLocationData } = useQuery( + routes.getFacilityAssetLocation, + { + pathParams: { + facility_external_id: qParams.facility, + external_id: qParams.last_consultation_current_bed__location, + }, + prefetch: !!qParams.last_consultation_current_bed__location, + } ); const { data: permittedFacilities } = useQuery( @@ -564,8 +444,8 @@ export const PatientManager = () => { }; let patientList: ReactNode[] = []; - if (data && data.length) { - patientList = data.map((patient: any) => { + if (data?.count) { + patientList = data.results.map((patient: any) => { let patientUrl = ""; if ( patient.last_consultation && @@ -814,16 +694,16 @@ export const PatientManager = () => {
); - } else if (data?.length) { + } else if (data?.count) { managePatients = ( <>
{patientList}
- + ); - } else if (data && data.length === 0) { + } else if (data && data.count === 0) { managePatients = (

No Patients Found

@@ -967,7 +847,7 @@ export const PatientManager = () => {
{ "Is Medico-Legal Case", "last_consultation_medico_legal_case" ), - value("Facility", "facility", facilityBadgeName), + value( + "Facility", + "facility", + qParams.facility ? facilityData?.name || "" : "" + ), value( "Location", "last_consultation_current_bed__location", - locationBadgeName + qParams.last_consultation_current_bed__location + ? facilityAssetLocationData?.name || + qParams.last_consultation_current_bed__locations + : "" ), badge("Facility Type", "facility_type"), - value("District", "district", districtName), + value( + "District", + "district", + qParams.district ? districtData?.name || "" : "" + ), ordering(), value("Category", "category", getTheCategoryFromId()), badge("Disease Status", "disease_status"), @@ -1067,7 +958,11 @@ export const PatientManager = () => { }, ...range("Age", "age"), badge("SRF ID", "srf_id"), - { name: "LSG Body", value: localbodyName, paramKey: "lsgBody" }, + { + name: "LSG Body", + value: qParams.lsgBody ? LocalBodyData?.name || "" : "", + paramKey: "lsgBody", + }, ...FILTER_BY_DIAGNOSES_KEYS.map((key) => value( DIAGNOSES_FILTER_LABELS[key], diff --git a/src/Components/Patient/PatientHome.tsx b/src/Components/Patient/PatientHome.tsx index 9b719ba31dd..22dc86117f4 100644 --- a/src/Components/Patient/PatientHome.tsx +++ b/src/Components/Patient/PatientHome.tsx @@ -1,23 +1,13 @@ import { navigate } from "raviger"; -import { lazy, useCallback, useEffect, useState } from "react"; -import { useDispatch } from "react-redux"; +import { lazy, useEffect, useState } from "react"; + import { DISCHARGE_REASONS, GENDER_TYPES, SAMPLE_TEST_STATUS, } from "../../Common/constants"; -import { statusType, useAbortableEffect } from "../../Common/utils"; -import { - getConsultationList, - listShiftRequests, - getPatient, - getSampleTestList, - patchSample, - patchPatient, - completeTransfer, -} from "../../Redux/actions"; + import * as Notification from "../../Utils/Notifications"; -import Pagination from "../Common/Pagination"; import { ConsultationCard } from "../Facility/ConsultationCard"; import { ConsultationModel } from "../Facility/models"; import { PatientModel, SampleTestModel } from "./models"; @@ -44,35 +34,18 @@ import useAuthUser from "../../Common/hooks/useAuthUser"; import useQuery from "../../Utils/request/useQuery"; import routes from "../../Redux/api"; import { InsuranceDetialsCard } from "./InsuranceDetailsCard"; +import request from "../../Utils/request/request"; +import PaginatedList from "../../CAREUI/misc/PaginatedList"; const Loading = lazy(() => import("../Common/Loading")); export const PatientHome = (props: any) => { const { facilityId, id } = props; - const dispatch: any = useDispatch(); const [showShifts, setShowShifts] = useState(false); const [isShiftClicked, setIsShiftClicked] = useState(false); - const [isShiftDataLoaded, setIsShiftDataLoaded] = useState(false); const [patientData, setPatientData] = useState({}); - const [consultationListData, setConsultationListData] = useState< - Array - >([]); - const [sampleListData, setSampleListData] = useState>( - [] - ); - const [activeShiftingData, setActiveShiftingData] = useState>([]); const [assignedVolunteerObject, setAssignedVolunteerObject] = useState(null); - const [isLoading, setIsLoading] = useState(false); - const [totalConsultationCount, setTotalConsultationCount] = useState(0); - const [currentConsultationPage, setCurrentConsultationPage] = useState(1); - const [consultationOffset, setConsultationOffset] = useState(0); - const [totalSampleListCount, setTotalSampleListCount] = useState(0); - const [currentSampleListPage, setCurrentSampleListPage] = useState(1); - const [sampleListOffset, setSampleListOffset] = useState(0); - const [isConsultationLoading, setIsConsultationLoading] = useState(false); - const [isSampleLoading, setIsSampleLoading] = useState(false); - const [sampleFlag, callSampleList] = useState(false); const authUser = useAuthUser(); const { t } = useTranslation(); const [selectedStatus, setSelectedStatus] = useState<{ @@ -94,13 +67,16 @@ export const PatientHome = (props: any) => { setAssignedVolunteerObject(patientData.assigned_to_object); }, [patientData.assigned_to_object]); - const handleTransferComplete = (shift: any) => { + const handleTransferComplete = async (shift: any) => { setModalFor({ ...modalFor, loading: true }); - dispatch(completeTransfer({ externalId: modalFor })).then(() => { - navigate( - `/facility/${shift.assigned_facility}/patient/${shift.patient}/consultation` - ); + await request(routes.completeTransfer, { + pathParams: { + id: modalFor.externalId ?? "", + }, }); + navigate( + `/facility/${shift.assigned_facility}/patient/${shift.patient}/consultation` + ); }; const { data: insuranceDetials } = useQuery(routes.listHCXPolicies, { @@ -110,52 +86,28 @@ export const PatientHome = (props: any) => { }, }); - const handleAssignedVolunteer = () => { - dispatch( - patchPatient( - { - assigned_to: assignedVolunteerObject - ? assignedVolunteerObject.id - : null, - }, - { id: patientData.id } - ) - ).then((response: any) => { - if ((response || {}).status === 200) { - const dummyPatientData = Object.assign({}, patientData); - dummyPatientData["assigned_to"] = assignedVolunteerObject; - setPatientData(dummyPatientData); - if (assignedVolunteerObject) - Notification.Success({ - msg: "Volunteer assigned successfully.", - }); - else - Notification.Success({ - msg: "Volunteer unassigned successfully.", - }); - document.location.reload(); - } - }); - setOpenAssignVolunteerDialog(false); - if (errors["assignedVolunteer"]) delete errors["assignedVolunteer"]; - }; - - const handlePatientTransfer = (value: boolean) => { + const handlePatientTransfer = async (value: boolean) => { const dummyPatientData = Object.assign({}, patientData); dummyPatientData["allow_transfer"] = value; - dispatch( - patchPatient({ allow_transfer: value }, { id: patientData.id }) - ).then((response: any) => { - if ((response || {}).status === 200) { - const dummyPatientData = Object.assign({}, patientData); - dummyPatientData["allow_transfer"] = value; - setPatientData(dummyPatientData); + await request(routes.patchPatient, { + pathParams: { + id: patientData.id as string, + }, - Notification.Success({ - msg: "Transfer status updated.", - }); - } + body: { allow_transfer: value }, + + onResponse: ({ res }) => { + if ((res || {}).status === 200) { + const dummyPatientData = Object.assign({}, patientData); + dummyPatientData["allow_transfer"] = value; + setPatientData(dummyPatientData); + + Notification.Success({ + msg: "Transfer status updated.", + }); + } + }, }); }; @@ -163,122 +115,58 @@ export const PatientHome = (props: any) => { setAssignedVolunteerObject(volunteer.value); }; - const limit = 5; - - const fetchpatient = useCallback( - async (status: statusType) => { - setIsLoading(true); - const patientRes = await dispatch(getPatient({ id })); - if (!status.aborted) { - if (patientRes && patientRes.data) { - setPatientData(patientRes.data); - } - setIsLoading(false); - } + const { loading: isLoading, refetch } = useQuery(routes.getPatient, { + pathParams: { + id, }, - [dispatch, id] - ); - - const fetchConsultation = useCallback( - async (status: statusType) => { - setIsConsultationLoading(true); - const consultationRes = await dispatch( - getConsultationList({ patient: id, limit, offset: consultationOffset }) - ); - if (!status.aborted) { - if ( - consultationRes && - consultationRes.data && - consultationRes.data.results - ) { - setConsultationListData(consultationRes.data.results); - setTotalConsultationCount(consultationRes.data.count); - } - setIsConsultationLoading(false); - } - }, - [dispatch, id, consultationOffset] - ); - - const fetchSampleTest = useCallback( - async (status: statusType) => { - setIsSampleLoading(true); - const sampleRes = await dispatch( - getSampleTestList( - { limit, offset: sampleListOffset }, - { patientId: id } - ) - ); - if (!status.aborted) { - if (sampleRes && sampleRes.data && sampleRes.data.results) { - setSampleListData(sampleRes.data.results); - setTotalSampleListCount(sampleRes.data.count); - } - setIsSampleLoading(false); + onResponse: ({ res, data }) => { + if (res?.ok && data) { + setPatientData(data); } - }, - [dispatch, id, sampleListOffset] - ); - - const fetchActiveShiftingData = useCallback( - async (status: statusType) => { - const shiftingRes = isShiftClicked - ? await dispatch(listShiftRequests({ patient: id }, "shift-list-call")) - : activeShiftingData; - setIsShiftDataLoaded(isShiftClicked); - if (!status.aborted) { - if (shiftingRes && shiftingRes.data && shiftingRes.data.results) { - const activeShiftingRes: any[] = shiftingRes.data.results; - setActiveShiftingData(activeShiftingRes); - } - } - }, - [dispatch, id, isShiftClicked] - ); - - useAbortableEffect( - (status: statusType) => { - fetchpatient(status); triggerGoal("Patient Profile Viewed", { facilityId: facilityId, userId: authUser.id, }); }, - [dispatch, fetchpatient] - ); - - useAbortableEffect( - (status: statusType) => { - fetchConsultation(status); - }, - [dispatch, fetchConsultation] - ); - - useAbortableEffect( - (status: statusType) => { - fetchSampleTest(status); - }, - [dispatch, fetchSampleTest, sampleFlag] - ); - - useAbortableEffect( - (status: statusType) => { - fetchActiveShiftingData(status); - }, - [dispatch, fetchActiveShiftingData] - ); + }); - const handleConsultationPagination = (page: number, limit: number) => { - const offset = (page - 1) * limit; - setCurrentConsultationPage(page); - setConsultationOffset(offset); + const handleAssignedVolunteer = async () => { + const { res, data } = await request(routes.patchPatient, { + pathParams: { + id: patientData.id as string, + }, + body: { + assigned_to: assignedVolunteerObject + ? assignedVolunteerObject.id + : null, + }, + }); + if (res?.ok && data) { + setPatientData(data); + if (assignedVolunteerObject) { + Notification.Success({ + msg: "Volunteer assigned successfully.", + }); + } else { + Notification.Success({ + msg: "Volunteer unassigned successfully.", + }); + } + refetch(); + } + setOpenAssignVolunteerDialog(false); + if (errors["assignedVolunteer"]) delete errors["assignedVolunteer"]; }; - const handleSampleListPagination = (page: number, limit: number) => { - const offset = (page - 1) * limit; - setCurrentSampleListPage(page); - setSampleListOffset(offset); - }; + const { loading: isShiftDataLoading, data: activeShiftingData } = useQuery( + routes.listShiftRequests, + { + query: { + patient: id, + }, + prefetch: isShiftClicked, + } + ); const confirmApproval = (status: number, sample: any) => { setSelectedStatus({ status, sample }); @@ -289,20 +177,25 @@ export const PatientHome = (props: any) => { const { status, sample } = selectedStatus; const sampleData = { id: sample.id, - status, + status: status.toString(), consultation: sample.consultation, }; const statusName = SAMPLE_TEST_STATUS.find((i) => i.id === status)?.desc; - const res = await dispatch(patchSample(sampleData, { id: sample.id })); - if (res && (res.status === 201 || res.status === 200)) { - Notification.Success({ - msg: `Request ${statusName}`, - }); - callSampleList(!sampleFlag); - } - - setShowAlertMessage(false); + await request(routes.patchSample, { + body: sampleData, + pathParams: { + id: sample.id, + }, + onResponse: ({ res }) => { + if (res?.ok) { + Notification.Success({ + msg: `Request ${statusName}`, + }); + } + setShowAlertMessage(false); + }, + }); }; if (isLoading) { @@ -334,57 +227,7 @@ export const PatientHome = (props: any) => { )); } - let consultationList, sampleList; - - if (isConsultationLoading) { - consultationList = ; - } else if (consultationListData.length === 0) { - consultationList = ( -
-
-
- No Data Found -
-
- ); - } else if (consultationListData.length > 0) { - consultationList = consultationListData.map((itemData, idx) => ( - - )); - } - - if (isSampleLoading) { - sampleList = ; - } else if (sampleListData.length === 0) { - sampleList = ( -
-
-
- No Data Found -
-
- ); - } else if (sampleListData.length > 0) { - sampleList = ( -
- {sampleListData.map((itemData, idx) => ( - - ))} -
- ); - } - - const isPatientInactive = (patientData: PatientModel, facilityId: number) => { + const isPatientInactive = (patientData: PatientModel, facilityId: string) => { return ( !patientData.is_active || !(patientData?.last_consultation?.facility === facilityId) @@ -798,8 +641,7 @@ export const PatientHome = (props: any) => { id="patient-allow-transfer" className="mt-4 w-full" disabled={ - !consultationListData || - !consultationListData.length || + !patientData.last_consultation?.id || !patientData.is_active } onClick={() => @@ -835,14 +677,14 @@ export const PatientHome = (props: any) => {
- {activeShiftingData.length ? ( - activeShiftingData.map((shift: any) => ( + {activeShiftingData?.count ? ( + activeShiftingData.results.map((shift: any) => (
{ )) ) : (
- {isShiftDataLoaded ? "No Shifting Records!" : "Loading..."} + {isShiftDataLoading ? "Loading..." : "No Shifting Records!"}
)}
@@ -1511,34 +1353,66 @@ export const PatientHome = (props: any) => {

Consultation History

- {consultationList} - {!isConsultationLoading && totalConsultationCount > limit && ( -
- -
- )} + + + {(_) => ( +
+ + + + > + {(item) => ( + + )} + +
+ +
+
+ )} +

Sample Test History

- {sampleList} - {!isSampleLoading && totalSampleListCount > limit && ( -
- -
- )} + + {(_, query) => ( +
+ + + + > + {(item) => ( + + )} + +
+ +
+
+ )} +
); diff --git a/src/Components/Patient/SampleDetails.tsx b/src/Components/Patient/SampleDetails.tsx index 9b08395a233..bcaf170cc4f 100644 --- a/src/Components/Patient/SampleDetails.tsx +++ b/src/Components/Patient/SampleDetails.tsx @@ -1,7 +1,6 @@ -import { FlowModel, SampleTestModel } from "./models"; +import { FlowModel } from "./models"; import { GENDER_TYPES, TEST_TYPE_CHOICES } from "../../Common/constants"; -import { statusType, useAbortableEffect } from "../../Common/utils"; -import { lazy, useCallback, useState } from "react"; +import { lazy } from "react"; import ButtonV2 from "../Common/components/ButtonV2"; import Card from "../../CAREUI/display/Card"; @@ -9,41 +8,29 @@ import { FileUpload } from "./FileUpload"; import Page from "../Common/components/Page"; import _ from "lodash-es"; import { formatAge, formatDateTime } from "../../Utils/utils"; -import { getTestSample } from "../../Redux/actions"; import { navigate } from "raviger"; -import { useDispatch } from "react-redux"; import { DetailRoute } from "../../Routers/types"; +import useQuery from "../../Utils/request/useQuery"; +import routes from "../../Redux/api"; const Loading = lazy(() => import("../Common/Loading")); export const SampleDetails = ({ id }: DetailRoute) => { - const dispatch: any = useDispatch(); - const [isLoading, setIsLoading] = useState(false); - const [sampleDetails, setSampleDetails] = useState({}); - - const fetchData = useCallback( - async (status: statusType) => { - setIsLoading(true); - const res = await dispatch(getTestSample(id)); - if (!status.aborted) { - if (res && res.data) { - setSampleDetails(res.data); - } else { + const { loading: isLoading, data: sampleDetails } = useQuery( + routes.getTestSample, + { + pathParams: { + id, + }, + onResponse: ({ res, data }) => { + if (!(res?.ok && data)) { navigate("/not-found"); } - setIsLoading(false); - } - }, - [dispatch, id] + }, + } ); - useAbortableEffect( - (status: statusType) => { - fetchData(status); - }, - [dispatch, fetchData, id] - ); const yesOrNoBadge = (param: any) => param ? ( Yes @@ -287,7 +274,7 @@ export const SampleDetails = ({ id }: DetailRoute) => { title="Sample Test Details" backUrl="/sample" options={ - sampleDetails.patient && ( + sampleDetails?.patient && (
{ Status:{" "} - {sampleDetails.status} + {sampleDetails?.status}
Result:{" "} - {sampleDetails.result} + {sampleDetails?.result}
Patient: - {sampleDetails.patient_name} + {sampleDetails?.patient_name}
- {sampleDetails.facility_object && ( + {sampleDetails?.facility_object && (
Facility: - {sampleDetails.facility_object.name} + {sampleDetails?.facility_object.name}
)}
Tested on: - {sampleDetails.date_of_result + {sampleDetails?.date_of_result ? formatDateTime(sampleDetails.date_of_result) : "-"}
Result on: - {sampleDetails.date_of_result + {sampleDetails?.date_of_result ? formatDateTime(sampleDetails.date_of_result) : "-"}
- {sampleDetails.fast_track && ( + {sampleDetails?.fast_track && (
Fast track testing reason:{" "} @@ -342,7 +329,7 @@ export const SampleDetails = ({ id }: DetailRoute) => { {sampleDetails.fast_track}
)} - {sampleDetails.doctor_name && ( + {sampleDetails?.doctor_name && (
Doctor's Name:{" "} @@ -350,21 +337,21 @@ export const SampleDetails = ({ id }: DetailRoute) => { {_.startCase(_.camelCase(sampleDetails.doctor_name))}
)} - {sampleDetails.diagnosis && ( + {sampleDetails?.diagnosis && (
Diagnosis: {sampleDetails.diagnosis}
)} - {sampleDetails.diff_diagnosis && ( + {sampleDetails?.diff_diagnosis && (
Differential diagnosis:{" "} - {sampleDetails.diff_diagnosis} + {sampleDetails?.diff_diagnosis}
)} - {sampleDetails.etiology_identified && ( + {sampleDetails?.etiology_identified && (
Etiology identified:{" "} @@ -376,15 +363,15 @@ export const SampleDetails = ({ id }: DetailRoute) => { Is Atypical presentation{" "} - {yesOrNoBadge(sampleDetails.is_atypical_presentation)} + {yesOrNoBadge(sampleDetails?.is_atypical_presentation)}
Is unusual course{" "} - {yesOrNoBadge(sampleDetails.is_unusual_course)} + {yesOrNoBadge(sampleDetails?.is_unusual_course)}
- {sampleDetails.atypical_presentation && ( + {sampleDetails?.atypical_presentation && (
Atypical presentation details:{" "} @@ -396,27 +383,27 @@ export const SampleDetails = ({ id }: DetailRoute) => { SARI - Severe Acute Respiratory illness{" "} - {yesOrNoBadge(sampleDetails.has_sari)} + {yesOrNoBadge(sampleDetails?.has_sari)}
ARI - Acute Respiratory illness{" "} - {yesOrNoBadge(sampleDetails.has_ari)} + {yesOrNoBadge(sampleDetails?.has_ari)}
Contact with confirmed carrier{" "} - {yesOrNoBadge(sampleDetails.patient_has_confirmed_contact)} + {yesOrNoBadge(sampleDetails?.patient_has_confirmed_contact)}
Contact with suspected carrier{" "} - {yesOrNoBadge(sampleDetails.patient_has_suspected_contact)} + {yesOrNoBadge(sampleDetails?.patient_has_suspected_contact)}
- {sampleDetails.patient_travel_history && + {sampleDetails?.patient_travel_history && sampleDetails.patient_travel_history.length !== 0 && (
@@ -425,7 +412,7 @@ export const SampleDetails = ({ id }: DetailRoute) => { {sampleDetails.patient_travel_history.join(", ")}
)} - {sampleDetails.sample_type && ( + {sampleDetails?.sample_type && (
Sample Type:{" "} @@ -438,12 +425,12 @@ export const SampleDetails = ({ id }: DetailRoute) => {

Details of patient

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

Sample Test History

- {sampleDetails.flow && + {sampleDetails?.flow && sampleDetails.flow.map((flow: FlowModel) => renderFlow(flow))}
diff --git a/src/Components/Patient/SampleFilters.tsx b/src/Components/Patient/SampleFilters.tsx index 8bebd135e0b..2a72f54204f 100644 --- a/src/Components/Patient/SampleFilters.tsx +++ b/src/Components/Patient/SampleFilters.tsx @@ -1,4 +1,3 @@ -import { useState, useEffect } from "react"; import { SAMPLE_TEST_STATUS, SAMPLE_TEST_RESULT, @@ -6,14 +5,14 @@ import { } from "../../Common/constants"; import { FacilitySelect } from "../Common/FacilitySelect"; import { FacilityModel } from "../Facility/models"; -import { getAnyFacility } from "../../Redux/actions"; -import { useDispatch } from "react-redux"; import useMergeState from "../../Common/hooks/useMergeState"; import FiltersSlideover from "../../CAREUI/interactive/FiltersSlideover"; import CircularProgress from "../Common/components/CircularProgress"; import { FieldLabel } from "../Form/FormFields/FormField"; import { SelectFormField } from "../Form/FormFields/SelectFormField"; import { FieldChangeEvent } from "../Form/FormFields/Utils"; +import useQuery from "../../Utils/request/useQuery"; +import routes from "../../Redux/api"; export default function UserFilter(props: any) { const { filter, onChange, closeFilter, removeFilters } = props; @@ -26,9 +25,6 @@ export default function UserFilter(props: any) { sample_type: filter.sample_type || "", }); - const [isFacilityLoading, setFacilityLoading] = useState(false); - const dispatch: any = useDispatch(); - const handleChange = ({ name, value }: FieldChangeEvent) => { setFilterState({ ...filterState, [name]: value }); }; @@ -44,21 +40,15 @@ export default function UserFilter(props: any) { onChange(data); }; - useEffect(() => { - async function fetchData() { - if (filter.facility) { - setFacilityLoading(true); - const { data: facilityData } = await dispatch( - getAnyFacility(filter.facility, "facility") - ); - setFilterState({ ...filterState, facility_ref: facilityData }); - setFacilityLoading(false); - } - } - fetchData(); - }, [dispatch]); - - console.log(filterState.sample_type); + const { loading: isFacilityLoading } = useQuery(routes.getAnyFacility, { + pathParams: { + id: filter.facility, + }, + prefetch: !!filter.facility, + onResponse: ({ data }) => { + setFilterState({ ...filterState, facility_ref: data }); + }, + }); return ( import("../Common/Loading")); @@ -56,34 +54,19 @@ function SampleReportSection({ title, fields }: ISampleReportSectionProps) { } export default function SampleReport(props: ISamplePreviewProps) { - const dispatch: any = useDispatch(); const { id, sampleId } = props; - const [isLoading, setIsLoading] = useState(false); - const [sampleData, setSampleData] = useState({}); let report: JSX.Element = <>; let reportData: JSX.Element = <>; - const fetchData = useCallback( - async (status: statusType) => { - setIsLoading(true); - const res: any = await dispatch(sampleReport(id, sampleId)); - - if (!status.aborted) { - if (res && res.data) { - setSampleData(res.data); - } - } - setIsLoading(false); - }, - [dispatch, id] - ); - - useAbortableEffect( - (status: statusType) => { - fetchData(status); - }, - [fetchData] + const { loading: isLoading, data: sampleData } = useQuery( + routes.sampleReport, + { + pathParams: { + id, + sampleId, + }, + } ); if (sampleData) { diff --git a/src/Components/Patient/SampleTest.tsx b/src/Components/Patient/SampleTest.tsx index 625e2104d0d..21a308fa393 100644 --- a/src/Components/Patient/SampleTest.tsx +++ b/src/Components/Patient/SampleTest.tsx @@ -1,9 +1,7 @@ import { navigate } from "raviger"; -import { useReducer, useState, useEffect, lazy } from "react"; -import { useDispatch } from "react-redux"; +import { useReducer, useState, lazy } from "react"; import { SAMPLE_TYPE_CHOICES, ICMR_CATEGORY } from "../../Common/constants"; -import { createSampleTest, getPatient } from "../../Redux/actions"; import * as Notification from "../../Utils/Notifications.js"; import { SampleTestModel } from "./models"; import { Cancel, Submit } from "../Common/components/ButtonV2"; @@ -16,6 +14,9 @@ import CheckBoxFormField from "../Form/FormFields/CheckBoxFormField"; import { FieldChangeEvent } from "../Form/FormFields/Utils"; import Page from "../Common/components/Page"; import { FacilitySelect } from "../Common/FacilitySelect"; +import request from "../../Utils/request/request"; +import routes from "../../Redux/api"; +import useQuery from "../../Utils/request/useQuery"; const Loading = lazy(() => import("../Common/Loading")); const initForm: SampleTestModel = { @@ -68,30 +69,18 @@ const sampleTestFormReducer = (state = initialState, action: any) => { export const SampleTest = ({ facilityId, patientId }: any) => { const { goBack } = useAppHistory(); - const dispatchAction: any = useDispatch(); const [state, dispatch] = useReducer(sampleTestFormReducer, initialState); const [isLoading, setIsLoading] = useState(false); - const [facilityName, setFacilityName] = useState(""); - const [patientName, setPatientName] = useState(""); const headerText = "Request Sample"; const buttonText = "Confirm your request to send sample for testing"; - useEffect(() => { - async function fetchPatientName() { - if (patientId) { - const res = await dispatchAction(getPatient({ id: patientId })); - if (res.data) { - setPatientName(res.data.name); - setFacilityName(res.data.facility_object.name); - } - } else { - setPatientName(""); - setFacilityName(""); - } - } - fetchPatientName(); - }, [dispatchAction, patientId]); + const { data } = useQuery(routes.getPatient, { + pathParams: { + id: patientId, + }, + prefetch: !!patientId, + }); const validateForm = () => { const errors = { ...initError }; @@ -170,15 +159,23 @@ export const SampleTest = ({ facilityId, patientId }: any) => { ? state.form.sample_type_other : undefined, }; - const res = await dispatchAction(createSampleTest(data, { patientId })); - setIsLoading(false); - if (res && res.data) { - dispatch({ type: "set_form", form: initForm }); - Notification.Success({ - msg: "Sample test created successfully", - }); - navigate(`/facility/${facilityId}/patient/${patientId}`); - } + + await request(routes.createSampleTest, { + pathParams: { + patientId, + }, + body: data, + onResponse: ({ res, data }) => { + setIsLoading(false); + if (res?.ok && data) { + dispatch({ type: "set_form", form: initForm }); + Notification.Success({ + msg: "Sample test created successfully", + }); + navigate(`/facility/${facilityId}/patient/${patientId}`); + } + }, + }); } }; @@ -201,8 +198,8 @@ export const SampleTest = ({ facilityId, patientId }: any) => { diff --git a/src/Components/Patient/SampleTestCard.tsx b/src/Components/Patient/SampleTestCard.tsx index 1ae1ff8671b..f2cc928bf50 100644 --- a/src/Components/Patient/SampleTestCard.tsx +++ b/src/Components/Patient/SampleTestCard.tsx @@ -1,9 +1,7 @@ import { navigate } from "raviger"; import { useState } from "react"; import { SampleTestModel } from "./models"; -import { useDispatch } from "react-redux"; import { SAMPLE_TEST_STATUS } from "../../Common/constants"; -import { patchSample } from "../../Redux/actions"; import * as Notification from "../../Utils/Notifications"; import UpdateStatusDialog from "./UpdateStatusDialog"; import _ from "lodash-es"; @@ -11,17 +9,19 @@ import { formatDateTime } from "../../Utils/utils"; import ButtonV2 from "../Common/components/ButtonV2"; import { NonReadOnlyUsers } from "../../Utils/AuthorizeFor"; import RelativeDateUserMention from "../Common/RelativeDateUserMention"; +import request from "../../Utils/request/request"; +import routes from "../../Redux/api"; interface SampleDetailsProps { facilityId: number; patientId: number; itemData: SampleTestModel; + refetch: () => void; handleApproval: (status: number, sample: SampleTestModel) => void; } export const SampleTestCard = (props: SampleDetailsProps) => { - const { itemData, handleApproval, facilityId, patientId } = props; - const dispatch: any = useDispatch(); + const { itemData, handleApproval, facilityId, patientId, refetch } = props; const [statusDialog, setStatusDialog] = useState<{ show: boolean; @@ -43,15 +43,21 @@ export const SampleTestCard = (props: SampleDetailsProps) => { sampleData.date_of_result = new Date().toISOString(); } const statusName = SAMPLE_TEST_STATUS.find((i) => i.id === status)?.desc; - - const res = await dispatch(patchSample(sampleData, { id: sample.id })); - if (res && (res.status === 201 || res.status === 200)) { - window.location.reload(); - Notification.Success({ - msg: `Success - ${statusName}`, - }); - } - dismissUpdateStatus(); + await request(routes.patchSample, { + pathParams: { + id: sample.id!, + }, + body: sampleData, + onResponse: ({ res }) => { + if (res?.ok) { + refetch(); + Notification.Success({ + msg: `Success - ${statusName}`, + }); + } + dismissUpdateStatus(); + }, + }); }; const showUpdateStatus = (sample: SampleTestModel) => { @@ -78,6 +84,7 @@ export const SampleTestCard = (props: SampleDetailsProps) => { : "bg-white hover:border-primary-500" } mt-4 block cursor-pointer rounded-lg border bg-white p-4 text-black shadow`} > +
test card this
navigate( diff --git a/src/Components/Patient/SampleViewAdmin.tsx b/src/Components/Patient/SampleViewAdmin.tsx index 5aca767e480..122f82aa7e2 100644 --- a/src/Components/Patient/SampleViewAdmin.tsx +++ b/src/Components/Patient/SampleViewAdmin.tsx @@ -1,20 +1,13 @@ import SampleFilter from "./SampleFilters"; import { navigate } from "raviger"; -import { useCallback, useState, useEffect, lazy } from "react"; -import { useDispatch } from "react-redux"; +import { useState, lazy } from "react"; import { SAMPLE_TEST_STATUS, SAMPLE_TEST_RESULT, SAMPLE_FLOW_RULES, SAMPLE_TYPE_CHOICES, } from "../../Common/constants"; -import { statusType, useAbortableEffect } from "../../Common/utils"; -import { - getTestList, - patchSample, - downloadSampleTests, - getAnyFacility, -} from "../../Redux/actions"; +import { downloadSampleTests } from "../../Redux/actions"; import * as Notification from "../../Utils/Notifications"; import { SampleTestModel } from "./models"; import UpdateStatusDialog from "./UpdateStatusDialog"; @@ -26,6 +19,9 @@ import CountBlock from "../../CAREUI/display/Count"; import CareIcon from "../../CAREUI/icons/CareIcon"; import { AdvancedFilterButton } from "../../CAREUI/interactive/FiltersSlideover"; import Page from "../Common/components/Page"; +import useQuery from "../../Utils/request/useQuery"; +import routes from "../../Redux/api"; +import request from "../../Utils/request/request"; const Loading = lazy(() => import("../Common/Loading")); @@ -41,70 +37,35 @@ export default function SampleViewAdmin() { limit: 10, cacheBlacklist: ["patient_name", "district_name"], }); - const dispatch: any = useDispatch(); - const initialData: any[] = []; let manageSamples: any = null; - const [sample, setSample] = useState>(initialData); - const [isLoading, setIsLoading] = useState(false); - const [totalCount, setTotalCount] = useState(0); - const [fetchFlag, callFetchData] = useState(false); - const [facilityName, setFacilityName] = useState(""); const [statusDialog, setStatusDialog] = useState<{ show: boolean; sample: SampleTestModel; }>({ show: false, sample: {} }); - useEffect(() => { - async function fetchData() { - if (!qParams.facility) return setFacilityName(""); - const res = await dispatch(getAnyFacility(qParams.facility)); - setFacilityName(res?.data?.name); - } - - fetchData(); - }, [dispatch, qParams.facility]); - - const fetchData = useCallback( - async (status: statusType) => { - setIsLoading(true); - const res = await dispatch( - getTestList({ - limit: resultsPerPage, - offset: (qParams.page ? qParams.page - 1 : 0) * resultsPerPage, - patient_name: qParams.patient_name || undefined, - district_name: qParams.district_name || undefined, - status: qParams.status || undefined, - result: qParams.result || undefined, - facility: qParams.facility || "", - sample_type: qParams.sample_type || undefined, - }) - ); - if (!status.aborted) { - if (res && res.data) { - setSample(res.data.results); - setTotalCount(res.data.count); - } - setIsLoading(false); - } + const { data: facilityData } = useQuery(routes.getAnyFacility, { + pathParams: { + id: qParams.facility, }, - [ - dispatch, - qParams.page, - qParams.patient_name, - qParams.district_name, - qParams.status, - qParams.result, - qParams.facility, - qParams.sample_type, - ] - ); + prefetch: !!qParams.facility, + }); - useAbortableEffect( - (status: statusType) => { - fetchData(status); + const { + loading: isLoading, + data: sampeleData, + refetch, + } = useQuery(routes.getTestSampleList, { + query: { + limit: resultsPerPage, + offset: (qParams.page ? qParams.page - 1 : 0) * resultsPerPage, + patient_name: qParams.patient_name || undefined, + district_name: qParams.district_name || undefined, + status: qParams.status || undefined, + result: qParams.result || undefined, + facility: qParams.facility || undefined, + sample_type: qParams.sample_type || undefined, }, - [fetchData, fetchFlag] - ); + }); const handleApproval = async ( sample: SampleTestModel, @@ -121,14 +82,22 @@ export default function SampleViewAdmin() { sampleData.date_of_result = new Date().toISOString(); } const statusName = SAMPLE_TEST_STATUS.find((i) => i.id === status)?.desc; - const res = await dispatch(patchSample(sampleData, { id: sample.id })); - if (res && (res.status === 201 || res.status === 200)) { - Notification.Success({ - msg: `Success - ${statusName}`, - }); - callFetchData(!fetchFlag); - } - dismissUpdateStatus(); + + await request(routes.patchSample, { + pathParams: { + id: sample.id || 0, + }, + body: sampleData, + onResponse: ({ res }) => { + if (res?.ok) { + Notification.Success({ + msg: `Success - ${statusName}`, + }); + refetch(); + } + dismissUpdateStatus(); + }, + }); }; const showUpdateStatus = (sample: SampleTestModel) => { @@ -163,8 +132,8 @@ export default function SampleViewAdmin() { .join("\n"); let sampleList: any[] = []; - if (sample && sample.length) { - sampleList = sample.map((item) => { + if (sampeleData?.count) { + sampleList = sampeleData.results.map((item) => { const status = String(item.status) as keyof typeof SAMPLE_FLOW_RULES; const statusText = SAMPLE_TEST_STATUS.find( (i) => i.text === status @@ -303,20 +272,20 @@ export default function SampleViewAdmin() { }); } - if (isLoading || !sample) { + if (isLoading || !sampeleData) { manageSamples = (
); - } else if (sample && sample.length) { + } else if (sampeleData?.count) { manageSamples = ( <> {sampleList} - + ); - } else if (sample && sample.length === 0) { + } else if (sampeleData?.count === 0) { manageSamples = (
@@ -351,7 +320,7 @@ export default function SampleViewAdmin() {
type.id === qParams.sample_type )?.text || "" ), - value("Facility", "facility", facilityName), + value( + "Facility", + "facility", + qParams.facility ? facilityData?.name || "" : "" + ), ]} />
diff --git a/src/Components/Patient/ShiftCreate.tsx b/src/Components/Patient/ShiftCreate.tsx index fb15039a2ea..0323ddb7c4b 100644 --- a/src/Components/Patient/ShiftCreate.tsx +++ b/src/Components/Patient/ShiftCreate.tsx @@ -7,8 +7,7 @@ import { SHIFTING_VEHICLE_CHOICES, } from "../../Common/constants"; import { Cancel, Submit } from "../Common/components/ButtonV2"; -import { createShift, getPatient } from "../../Redux/actions"; -import { lazy, useEffect, useReducer, useState } from "react"; +import { lazy, useReducer, useState } from "react"; import { FacilitySelect } from "../Common/FacilitySelect"; import { FieldChangeEvent } from "../Form/FormFields/Utils"; @@ -22,28 +21,27 @@ import { parsePhoneNumber } from "../../Utils/utils.js"; import { phonePreg } from "../../Common/validation"; import useAppHistory from "../../Common/hooks/useAppHistory"; import useConfig from "../../Common/hooks/useConfig"; -import { useDispatch } from "react-redux"; import { useTranslation } from "react-i18next"; import Page from "../Common/components/Page.js"; import Card from "../../CAREUI/display/Card.js"; import CheckBoxFormField from "../Form/FormFields/CheckBoxFormField.js"; import { SelectFormField } from "../Form/FormFields/SelectFormField.js"; import { PhoneNumberValidator } from "../Form/FieldValidators.js"; +import useQuery from "../../Utils/request/useQuery.js"; +import routes from "../../Redux/api.js"; +import request from "../../Utils/request/request.js"; const Loading = lazy(() => import("../Common/Loading")); interface patientShiftProps { - facilityId: number; - patientId: number; + facilityId: string; + patientId: string; } export const ShiftCreate = (props: patientShiftProps) => { const { goBack } = useAppHistory(); const { facilityId, patientId } = props; - const dispatchAction: any = useDispatch(); const [isLoading, setIsLoading] = useState(false); - const [facilityName, setFacilityName] = useState(""); - const [patientName, setPatientName] = useState(""); const [patientCategory, setPatientCategory] = useState(); const { t } = useTranslation(); const { wartime_shifting } = useConfig(); @@ -109,27 +107,22 @@ export const ShiftCreate = (props: patientShiftProps) => { errors: { ...initError }, }; - useEffect(() => { - async function fetchPatientName() { - if (patientId) { - const res = await dispatchAction(getPatient({ id: patientId })); - if (res.data) { - const patient_category = - res.data.last_consultation?.last_daily_round?.patient_category ?? - res.data.last_consultation?.category; - setPatientCategory( - PATIENT_CATEGORIES.find((c) => c.text === patient_category)?.id - ); - setPatientName(res.data.name); - setFacilityName(res.data.facility_object.name); - } - } else { - setPatientName(""); - setFacilityName(""); + const { data: patientData } = useQuery(routes.getPatient, { + pathParams: { + id: patientId, + }, + prefetch: !!patientId, + onResponse: ({ data }) => { + if (data) { + const patient_category = + data.last_consultation?.last_daily_round?.patient_category ?? + data.last_consultation?.category; + setPatientCategory( + PATIENT_CATEGORIES.find((c) => c.text === patient_category)?.id + ); } - } - fetchPatientName(); - }, [dispatchAction, patientId]); + }, + }); const shiftFormReducer = (state = initialState, action: any) => { switch (action.type) { @@ -242,17 +235,22 @@ export const ShiftCreate = (props: patientShiftProps) => { ambulance_number: state.form.ambulance_number, }; - const res = await dispatchAction(createShift(data)); - setIsLoading(false); + await request(routes.createShift, { + body: data, - if (res && res.data && (res.status == 201 || res.status == 200)) { - await dispatch({ type: "set_form", form: initForm }); - Notification.Success({ - msg: "Shift request created successfully", - }); + onResponse: ({ res, data }) => { + setIsLoading(false); - navigate(`/shifting/${res.data.id}`); - } + if (res?.ok && data) { + dispatch({ type: "set_form", form: initForm }); + Notification.Success({ + msg: "Shift request created successfully", + }); + + navigate(`/shifting/${data.id}`); + } + }, + }); } }; @@ -271,8 +269,8 @@ export const ShiftCreate = (props: patientShiftProps) => { diff --git a/src/Redux/actions.tsx b/src/Redux/actions.tsx index 280abbce5cc..cfe298bda82 100644 --- a/src/Redux/actions.tsx +++ b/src/Redux/actions.tsx @@ -20,31 +20,9 @@ export const getFacilityUsers = (id: string, params?: object) => { ); }; -export const getFacilityAssetLocation = ( - facility_external_id: string, - external_id: string -) => - fireRequest( - "getFacilityAssetLocation", - [], - {}, - { facility_external_id, external_id } - ); - // asset bed export const listAssetBeds = (params: object, altKey?: string) => fireRequest("listAssetBeds", [], params, {}, altKey); -export const createAssetBed = ( - params: object, - asset_id: string, - bed_id: string -) => - fireRequest( - "createAssetBed", - [], - { ...params, asset: asset_id, bed: bed_id }, - {} - ); export const partialUpdateAssetBed = (params: object, asset_id: string) => fireRequest( @@ -99,6 +77,11 @@ export const getPatient = (pathParam: object) => { export const updatePatient = (params: object, pathParam: object) => { return fireRequest("updatePatient", [], params, pathParam); }; + +export const transferPatient = (params: object, pathParam: object) => { + return fireRequest("transferPatient", [], params, pathParam); +}; + export const patchPatient = (params: object, pathParam: object) => { return fireRequest("patchPatient", [], params, pathParam); }; @@ -114,9 +97,6 @@ export const getDistrictByState = (pathParam: object) => { export const getDistrictByName = (params: object) => { return fireRequest("getDistrictByName", [], params, null); }; -export const getDistrict = (id: number, key?: string) => { - return fireRequest("getDistrict", [], {}, { id: id }, key); -}; export const getLocalbodyByDistrict = (pathParam: object) => { return fireRequest("getLocalbodyByDistrict", [], {}, pathParam); @@ -126,30 +106,7 @@ export const getWardByLocalBody = (pathParam: object) => { return fireRequest("getWardByLocalBody", [], {}, pathParam); }; -// Local Body -export const getLocalBody = (pathParam: object) => { - return fireRequest("getLocalBody", [], {}, pathParam); -}; - // Sample Test -export const getSampleTestList = (params: object, pathParam: object) => { - return fireRequest("sampleTestList", [], params, pathParam); -}; -export const createSampleTest = (params: object, pathParam: object) => { - return fireRequest("createSampleTest", [], params, pathParam); -}; -export const sampleReport = (id: string, sampleId: string) => { - return fireRequest("sampleReport", [], {}, { id, sampleId }); -}; -export const getTestList = (params: object) => { - return fireRequest("getTestSampleList", [], params); -}; -export const getTestSample = (id: string) => { - return fireRequest("getTestSample", [id], {}); -}; -export const patchSample = (params: object, pathParam: object) => { - return fireRequest("patchSample", [], params, pathParam); -}; export const downloadSampleTests = (params: object) => { return fireRequest("getTestSampleList", [], { ...params, csv: 1 }); }; @@ -173,9 +130,6 @@ export const getConsultationDailyRoundsDetails = (pathParam: object) => { export const createConsultation = (params: object) => { return fireRequest("createConsultation", [], params); }; -export const getConsultationList = (params: object) => { - return fireRequest("getConsultationList", [], params); -}; export const getConsultation = (id: string) => { return fireRequest("getConsultation", [], {}, { id: id }); }; @@ -204,17 +158,10 @@ export const dischargePatient = (params: object, pathParams: object) => { }; //Shift -export const createShift = (params: object) => { - return fireRequest("createShift", [], params); -}; - export const listShiftRequests = (params: object, key: string) => { return fireRequest("listShiftRequests", [], params, null, key); }; -export const completeTransfer = (pathParams: object) => { - return fireRequest("completeTransfer", [], {}, pathParams); -}; export const downloadShiftRequests = (params: object) => { return fireRequest("downloadShiftRequests", [], params); }; diff --git a/src/Redux/api.tsx b/src/Redux/api.tsx index 4893bfbd33f..8b2a3ae08c2 100644 --- a/src/Redux/api.tsx +++ b/src/Redux/api.tsx @@ -74,7 +74,12 @@ import { UserModel, } from "../Components/Users/models"; import { Prescription } from "../Components/Medicine/models"; -import { DailyRoundsModel, PatientModel } from "../Components/Patient/models"; +import { + DailyRoundsModel, + PatientModel, + SampleReportModel, + SampleTestModel, +} from "../Components/Patient/models"; import { PaginatedResponse } from "../Utils/request/types"; import { NotificationData, @@ -505,6 +510,8 @@ const routes = { }, getConsultationList: { path: "/api/v1/consultation/", + method: "GET", + TRes: Type>(), }, createConsultation: { path: "/api/v1/consultation/", @@ -549,6 +556,8 @@ const routes = { getDailyReport: { path: "/api/v1/consultation/{consultationId}/daily_rounds/{id}/", + method: "GET", + TRes: Type(), }, dailyRoundsAnalyse: { path: "/api/v1/consultation/{consultationId}/daily_rounds/analyse/", @@ -644,6 +653,8 @@ const routes = { }, patientList: { path: "/api/v1/patient/", + method: "GET", + TRes: Type>(), }, addPatient: { path: "/api/v1/patient/", @@ -651,7 +662,7 @@ const routes = { }, getPatient: { path: "/api/v1/patient/{id}/", - TBody: Type(), + method: "GET", TRes: Type(), }, updatePatient: { @@ -661,6 +672,8 @@ const routes = { patchPatient: { path: "/api/v1/patient/{id}/", method: "PATCH", + TBody: Type>(), + TRes: Type(), }, transferPatient: { path: "/api/v1/patient/{id}/transfer/", @@ -690,13 +703,19 @@ const routes = { }, sampleTestList: { path: "/api/v1/patient/{patientId}/test_sample/", + method: "GET", + TRes: Type>(), }, createSampleTest: { path: "/api/v1/patient/{patientId}/test_sample/", method: "POST", + TRes: Type(), + TBody: Type(), }, sampleReport: { - path: "/api/v1/patient/{id}/test_sample/{sampleId}/icmr_sample", + path: "/api/v1/patient/{id}/test_sample/{sampleId}/icmr_sample/", + method: "GET", + TRes: Type(), }, // External Results @@ -803,13 +822,19 @@ const routes = { // Sample Test getTestSampleList: { path: "/api/v1/test_sample/", + method: "GET", + TRes: Type>(), }, getTestSample: { - path: "/api/v1/test_sample", + path: "/api/v1/test_sample/{id}/", + method: "GET", + TRes: Type(), }, patchSample: { path: "/api/v1/test_sample/{id}/", method: "PATCH", + TBody: Type(), + TRes: Type(), }, //inventory @@ -905,15 +930,17 @@ const routes = { createShift: { path: "/api/v1/shift/", method: "POST", + TBody: Type>(), + TRes: Type(), }, updateShift: { - path: "/api/v1/shift/{id}", + path: "/api/v1/shift/{id}/", method: "PUT", TBody: Type(), TRes: Type(), }, deleteShiftRecord: { - path: "/api/v1/shift/{id}", + path: "/api/v1/shift/{id}/", method: "DELETE", TRes: Type<{ detail: string }>(), },