diff --git a/src/Components/ExternalResult/ResultList.tsx b/src/Components/ExternalResult/ResultList.tsx
index 74fbf8430b0..d148b26e3f5 100644
--- a/src/Components/ExternalResult/ResultList.tsx
+++ b/src/Components/ExternalResult/ResultList.tsx
@@ -1,12 +1,10 @@
import ButtonV2 from "../Common/components/ButtonV2";
import { navigate } from "raviger";
-import { lazy, useEffect, useState } from "react";
-import { useDispatch } from "react-redux";
+import { lazy, useState } from "react";
import { externalResultList } from "../../Redux/actions";
import ListFilter from "./ListFilter";
import FacilitiesSelectDialogue from "./FacilitiesSelectDialogue";
import { FacilityModel } from "../Facility/models";
-import { parsePhoneNumber } from "../../Utils/utils";
import SearchInput from "../Form/SearchInput";
import useFilters from "../../Common/hooks/useFilters";
import CareIcon from "../../CAREUI/icons/CareIcon";
@@ -15,14 +13,12 @@ import PhoneNumberFormField from "../Form/FormFields/PhoneNumberFormField";
import CountBlock from "../../CAREUI/display/Count";
import { AdvancedFilterButton } from "../../CAREUI/interactive/FiltersSlideover";
import Page from "../Common/components/Page";
-
+import routes from "../../Redux/api";
+import useQuery from "../../Utils/request/useQuery";
+import { parsePhoneNumber } from "../../Utils/utils";
const Loading = lazy(() => import("../Common/Loading"));
export default function ResultList() {
- const dispatch: any = useDispatch();
- const [data, setData] = useState([]);
- const [isLoading, setIsLoading] = useState(false);
- const [totalCount, setTotalCount] = useState(0);
const {
qParams,
updateQuery,
@@ -57,61 +53,31 @@ export default function ResultList() {
setPhoneNumberError("Enter a valid number");
};
+ const params = {
+ page: qParams.page || 1,
+ name: qParams.name || "",
+ mobile_number: qParams.mobile_number
+ ? parsePhoneNumber(qParams.mobile_number) ?? ""
+ : "",
+ wards: qParams.wards || undefined,
+ local_bodies: qParams.local_bodies || undefined,
+ created_date_before: qParams.created_date_before || undefined,
+ created_date_after: qParams.created_date_after || undefined,
+ result_date_before: qParams.result_date_before || undefined,
+ result_date_after: qParams.result_date_after || undefined,
+ sample_collection_date_after:
+ qParams.sample_collection_date_after || undefined,
+ sample_collection_date_before:
+ qParams.sample_collection_date_before || undefined,
+ offset: (qParams.page ? qParams.page - 1 : 0) * resultsPerPage,
+ srf_id: qParams.srf_id || undefined,
+ };
- let manageResults: any = null;
- useEffect(() => {
- setIsLoading(true);
- const params = {
- page: qParams.page || 1,
- name: qParams.name || "",
- mobile_number: qParams.mobile_number
- ? parsePhoneNumber(qParams.mobile_number) ?? ""
- : "",
- wards: qParams.wards || undefined,
- local_bodies: qParams.local_bodies || undefined,
- created_date_before: qParams.created_date_before || undefined,
- created_date_after: qParams.created_date_after || undefined,
- result_date_before: qParams.result_date_before || undefined,
- result_date_after: qParams.result_date_after || undefined,
- sample_collection_date_after:
- qParams.sample_collection_date_after || undefined,
- sample_collection_date_before:
- qParams.sample_collection_date_before || undefined,
- offset: (qParams.page ? qParams.page - 1 : 0) * resultsPerPage,
- srf_id: qParams.srf_id || undefined,
- };
-
- dispatch(externalResultList(params, "externalResultList"))
- .then((res: any) => {
- if (res && res.data) {
- setData(res.data.results);
- setTotalCount(res.data.count);
- setIsLoading(false);
- }
- })
- .catch(() => {
- setIsLoading(false);
- });
+ const { data, loading } = useQuery(routes.externalResultList, {
+ query: params,
+ });
- if (!params.mobile_number) {
- setPhoneNum("+91");
- }
- }, [
- dispatch,
- qParams.name,
- qParams.page,
- qParams.mobile_number,
- qParams.wards,
- qParams.created_date_before,
- qParams.created_date_after,
- qParams.result_date_before,
- qParams.result_date_after,
- qParams.sample_collection_date_after,
- qParams.sample_collection_date_before,
- qParams.local_bodies,
- qParams.srf_id,
- dataList,
- ]);
+ let manageResults: any = null;
const removeLSGFilter = (paramKey: any, id: any) => {
const updatedLsgList = dataList.lsgList.filter((x: any) => x.id !== id);
@@ -158,8 +124,8 @@ export default function ResultList() {
};
let resultList: any[] = [];
- if (data && data.length) {
- resultList = data.map((result: any) => {
+ if (data?.results.length) {
+ resultList = data.results.map((result: any) => {
const resultUrl = `/external_results/${result.id}`;
return (
);
- } else if (data && data.length) {
+ } else if (data?.results.length) {
manageResults = <>{resultList}>;
- } else if (data && data.length === 0) {
+ } else if (data?.results.length === 0) {
manageResults = (
@@ -286,8 +252,8 @@ export default function ResultList() {
@@ -358,7 +324,7 @@ export default function ResultList() {
-
+
import("../Common/Loading"));
@@ -63,79 +57,70 @@ export default function UpdateResult(props: any) {
const { id } = props;
const { goBack } = useAppHistory();
- const dispatchAction: any = useDispatch();
const [state, dispatch] = useReducer(FormReducer, initialState);
- const [isLoading, setIsLoading] = useState(false);
+ const [isLoading, setIsLoading] = useState(true);
const [isLocalbodyLoading, setIsLocalbodyLoading] = useState(false);
const [isWardLoading, setIsWardLoading] = useState(false);
const [localBody, setLocalBody] = useState(initialLocalbodies);
const [ward, setWard] = useState(initialLocalbodies);
- const fetchData = useCallback(
- async (status: statusType) => {
- setIsLoading(true);
- const res = await dispatchAction(externalResult({ id: id }));
- if (!status.aborted) {
- if (res && res.data) {
- const form = { ...state.form };
- form["name"] = res.data.name;
- form["age"] = res.data.age;
- form["age_in"] = res.data.age_in;
- form["srf_id"] = res.data.srf_id;
- form["address"] = res.data.address;
- form["district"] = res.data.district_object.name;
- form["local_body"] = String(res.data.local_body);
- form["ward"] = String(res.data.ward);
- form["patient_created"] = String(res.data.patient_created);
+ const { loading } = useQuery(routes.externalResult, {
+ pathParams: { id },
+ onResponse: async ({ res, data }) => {
+ if (res && data) {
+ const form = { ...state.form };
+ form["name"] = data.name;
+ form["age"] = data.age;
+ form["age_in"] = data.age_in;
+ form["srf_id"] = data.srf_id;
+ form["address"] = data.address;
+ form["district"] = data.district_object.name;
+ form["local_body"] = String(data.local_body);
+ form["ward"] = String(data.ward);
+ form["patient_created"] = String(data.patient_created);
- dispatch({ type: "set_form", form });
+ dispatch({ type: "set_form", form });
- Promise.all([
- fetchLocalBody(res.data.district),
- fetchWards(res.data.local_body),
- ]);
- }
+ Promise.all([
+ fetchLocalBody(data.district),
+ fetchWards(data.local_body),
+ ]);
setIsLoading(false);
}
},
- [props.id, dispatchAction]
- );
+ });
- const fetchLocalBody = useCallback(
- async (id: string) => {
- if (Number(id) > 0) {
- setIsLocalbodyLoading(true);
- const localBodyList = await dispatchAction(
- getLocalbodyByDistrict({ id })
- );
+ const fetchLocalBody = async (id: number) => {
+ if (Number(id) > 0) {
+ setIsLocalbodyLoading(true);
+ const { res, data } = await request(routes.getLocalbodyByDistrict, {
+ pathParams: { id: String(id) },
+ });
+ if (res && data) {
setIsLocalbodyLoading(false);
- setLocalBody([...initialLocalbodies, ...localBodyList.data]);
- } else {
- setLocalBody(initialLocalbodies);
+ setLocalBody([...initialLocalbodies, ...data]);
}
- },
- [dispatchAction]
- );
+ } else {
+ setLocalBody(initialLocalbodies);
+ }
+ };
const fetchWards = useCallback(
- async (id: string) => {
+ async (id: number) => {
if (Number(id) > 0) {
setIsWardLoading(true);
- const wardList = await dispatchAction(getWardByLocalBody({ id }));
+ const { res, data } = await request(routes.getWardByLocalBody, {
+ pathParams: { id: String(id) },
+ });
+ if (res && data) {
+ setWard([...initialWard, ...data.results]);
+ }
setIsWardLoading(false);
- setWard([...initialWard, ...wardList.data.results]);
} else {
setWard(initialLocalbodies);
}
},
- [dispatchAction]
- );
-
- useAbortableEffect(
- (status: statusType) => {
- fetchData(status);
- },
- [fetchData]
+ [props.id]
);
const validateForm = () => {
@@ -195,15 +180,20 @@ export default function UpdateResult(props: any) {
const validForm = validateForm();
if (validForm) {
setIsLoading(true);
- const data = {
+ const rdata = {
address: state.form.address ? state.form.address : undefined,
local_body: state.form.local_body ? state.form.local_body : undefined,
ward: state.form.ward,
patient_created: state.form.patient_created === "true",
};
- const res = await dispatchAction(partialUpdateExternalResult(id, data));
+
+ const { res, data } = await request(routes.partialUpdateExternalResult, {
+ pathParams: { id },
+ body: rdata,
+ });
+
setIsLoading(false);
- if (res && res.data) {
+ if (res && data) {
dispatch({ type: "set_form", form: initForm });
Notification.Success({
msg: "External Result updated successfully",
@@ -213,7 +203,7 @@ export default function UpdateResult(props: any) {
}
};
- if (isLoading) {
+ if (isLoading || loading) {
return ;
}
@@ -262,10 +252,7 @@ export default function UpdateResult(props: any) {
options={localBody}
optionLabel={(localBody) => localBody.name}
optionValue={(localBody) => localBody.id}
- onChange={(e) => [
- handleChange(e),
- fetchWards(String(e.value)),
- ]}
+ onChange={(e) => [handleChange(e), fetchWards(e.value)]}
error={state.errors.local_body}
/>
)}
diff --git a/src/Components/ExternalResult/models.ts b/src/Components/ExternalResult/models.ts
new file mode 100644
index 00000000000..8ccaba04d05
--- /dev/null
+++ b/src/Components/ExternalResult/models.ts
@@ -0,0 +1,72 @@
+export interface IExternalResultUploadCsv {
+ sample_tests: any[];
+}
+
+export interface IExternalResult {
+ id: number;
+ name: string;
+ age: number;
+ age_in: string;
+ test_type: string;
+ result: string;
+ result_date: string;
+ patient_created: boolean;
+ gender: string;
+ source: string;
+ is_repeat: boolean;
+ mobile_number: string;
+ patient_status: string;
+ sample_type: string;
+ sample_collection_date: string;
+ patient_category: string;
+ srf_id: string;
+ district_object: {
+ id: number;
+ name: string;
+ state: number;
+ };
+ district: number;
+ ward: number;
+ local_body: number;
+ address: string;
+ ward_object: {
+ id: number;
+ number: number;
+ name: string;
+ };
+ local_body_object: {
+ id: number;
+ name: string;
+ };
+}
+
+export interface ILocalBodies {
+ id: number;
+ name: string;
+ state: number;
+ number: number;
+ body_type: number;
+ localbody_code: string;
+ district: number;
+}
+
+export interface IDeleteExternalResult {
+ detail: string;
+}
+
+export interface IPartialUpdateExternalResult {
+ address: string;
+ ward: number;
+ local_body: number;
+ patient_created: boolean;
+}
+
+export interface ILocalBodyByDistrict {
+ id: number;
+ name: string;
+ state: number;
+}
+
+export interface IExternalResultCsv {
+ sample_tests: Partial[];
+}
diff --git a/src/Redux/actions.tsx b/src/Redux/actions.tsx
index 26e006f4cea..06a12796737 100644
--- a/src/Redux/actions.tsx
+++ b/src/Redux/actions.tsx
@@ -668,13 +668,6 @@ export const externalResultList = (params: object, altKey: string) => {
export const externalResult = (pathParam: object) => {
return fireRequest("externalResult", [], {}, pathParam);
};
-export const externalResultUploadCsv = (params: object) => {
- return fireRequest("externalResultUploadCsv", [], params);
-};
-
-export const deleteExternalResult = (id: string) => {
- return fireRequest("deleteExternalResult", [id], {});
-};
export const updateExternalResult = (id: number, params: object) => {
return fireRequest("updateExternalResult", [], params, { id });
diff --git a/src/Redux/api.tsx b/src/Redux/api.tsx
index 8a4ca5cf1df..02c38afcc5a 100644
--- a/src/Redux/api.tsx
+++ b/src/Redux/api.tsx
@@ -1,6 +1,14 @@
import { IConfig } from "../Common/hooks/useConfig";
import { AssetData } from "../Components/Assets/AssetTypes";
-import { LocationModel } from "../Components/Facility/models";
+import {
+ IDeleteExternalResult,
+ IExternalResult,
+ IExternalResultCsv,
+ ILocalBodies,
+ ILocalBodyByDistrict,
+ IPartialUpdateExternalResult,
+} from "../Components/ExternalResult/models";
+import { LocationModel, WardModel } from "../Components/Facility/models";
import { Prescription } from "../Components/Medicine/models";
import { UserModel } from "../Components/Users/models";
import { PaginatedResponse } from "../Utils/request/types";
@@ -501,18 +509,25 @@ const routes = {
// External Results
externalResultList: {
path: "/api/v1/external_result/",
+ method: "GET",
+ TRes: Type>(),
},
externalResult: {
path: "/api/v1/external_result/{id}/",
+ method: "GET",
+ TRes: Type(),
},
externalResultUploadCsv: {
path: "/api/v1/external_result/bulk_upsert/",
method: "POST",
+ TBody: Type(),
+ TRes: Type(),
},
deleteExternalResult: {
- path: "/api/v1/external_result",
+ path: "/api/v1/external_result/{id}/",
method: "DELETE",
+ TRes: Type(),
},
updateExternalResult: {
@@ -523,6 +538,8 @@ const routes = {
partialUpdateExternalResult: {
path: "/api/v1/external_result/{id}/",
method: "PATCH",
+ TRes: Type(),
+ TBody: Type(),
},
// States
@@ -547,9 +564,13 @@ const routes = {
},
getAllLocalBodyByDistrict: {
path: "/api/v1/district/{id}/get_all_local_body/",
+ method: "GET",
+ TRes: Type(),
},
getLocalbodyByDistrict: {
path: "/api/v1/district/{id}/local_bodies/",
+ method: "GET",
+ TRes: Type(),
},
// Local Body
@@ -572,6 +593,8 @@ const routes = {
},
getWardByLocalBody: {
path: "/api/v1/ward/?local_body={id}",
+ method: "GET",
+ TRes: Type>(),
},
// Sample Test
diff --git a/src/Utils/request/request.ts b/src/Utils/request/request.ts
index 2d735734aae..d428107b64c 100644
--- a/src/Utils/request/request.ts
+++ b/src/Utils/request/request.ts
@@ -38,7 +38,7 @@ export default async function request(
try {
const res = await fetch(url, options);
- const data: TData = await res.json();
+ const data = await getResponseBody(res);
result = {
res,
@@ -61,3 +61,21 @@ export default async function request(
);
return result;
}
+
+async function getResponseBody(res: Response): Promise {
+ if (!(res.headers.get("content-length") !== "0")) {
+ return null as TData;
+ }
+
+ const isJson = res.headers.get("content-type")?.includes("application/json");
+
+ if (!isJson) {
+ return (await res.text()) as TData;
+ }
+
+ try {
+ return await res.json();
+ } catch {
+ return (await res.text()) as TData;
+ }
+}
From 7e29f250190ad65ff7726842a133694fd6bf5b86 Mon Sep 17 00:00:00 2001
From: Gokulram A
Date: Tue, 17 Oct 2023 06:33:58 +0530
Subject: [PATCH 4/5] Added cypress test to verify warranty expiry label on an
asset (#6428)
* added cypress test to verify warranty expiry label
* updated spec to check if the warranty expiry label goes off once updated
* verify the last change
---------
Co-authored-by: Mohammed Nihal <57055998+nihal467@users.noreply.github.com>
---
cypress/e2e/assets_spec/assets_manage.cy.ts | 33 +++++++++++++++++++++
cypress/pageobject/Asset/AssetCreation.ts | 27 +++++++++++++++--
src/CAREUI/display/Chip.tsx | 2 ++
src/Components/Assets/AssetsList.tsx | 3 ++
4 files changed, 63 insertions(+), 2 deletions(-)
diff --git a/cypress/e2e/assets_spec/assets_manage.cy.ts b/cypress/e2e/assets_spec/assets_manage.cy.ts
index 34c554b374e..8b440f68761 100644
--- a/cypress/e2e/assets_spec/assets_manage.cy.ts
+++ b/cypress/e2e/assets_spec/assets_manage.cy.ts
@@ -5,6 +5,12 @@ import { AssetSearchPage } from "../../pageobject/Asset/AssetSearch";
import FacilityPage from "../../pageobject/Facility/FacilityCreation";
import { AssetFilters } from "../../pageobject/Asset/AssetFilters";
+function addDaysToDate(numberOfDays: number) {
+ const inputDate = new Date();
+ inputDate.setDate(inputDate.getDate() + numberOfDays);
+ return inputDate.toISOString().split("T")[0];
+}
+
describe("Asset", () => {
const assetPage = new AssetPage();
const loginPage = new LoginPage();
@@ -26,6 +32,33 @@ describe("Asset", () => {
cy.awaitUrl("/assets");
});
+ it("Verify Asset Warranty Expiry Label", () => {
+ assetSearchPage.typeSearchKeyword(assetname);
+ assetSearchPage.pressEnter();
+ assetSearchPage.verifyBadgeContent(assetname);
+ assetSearchPage.clickAssetByName(assetname);
+ assetPage.clickupdatedetailbutton();
+ assetPage.scrollintoWarrantyDetails();
+ assetPage.enterWarrantyExpiryDate(addDaysToDate(100)); // greater than 3 months
+ assetPage.clickassetupdatebutton();
+ assetPage.verifyWarrantyExpiryLabel("");
+ assetPage.clickupdatedetailbutton();
+ assetPage.scrollintoWarrantyDetails();
+ assetPage.enterWarrantyExpiryDate(addDaysToDate(80)); // less than 3 months
+ assetPage.clickassetupdatebutton();
+ assetPage.verifyWarrantyExpiryLabel("3 months");
+ assetPage.clickupdatedetailbutton();
+ assetPage.scrollintoWarrantyDetails();
+ assetPage.enterWarrantyExpiryDate(addDaysToDate(20)); // less than 1 month
+ assetPage.clickassetupdatebutton();
+ assetPage.verifyWarrantyExpiryLabel("1 month");
+ assetPage.clickupdatedetailbutton();
+ assetPage.scrollintoWarrantyDetails();
+ assetPage.enterWarrantyExpiryDate(addDaysToDate(100)); // check for greater than 3 months again to verify the label is removed
+ assetPage.clickassetupdatebutton();
+ assetPage.verifyWarrantyExpiryLabel("");
+ });
+
it("Create & Edit a service history and verify reflection", () => {
assetSearchPage.typeSearchKeyword(assetname);
assetSearchPage.pressEnter();
diff --git a/cypress/pageobject/Asset/AssetCreation.ts b/cypress/pageobject/Asset/AssetCreation.ts
index 2c727820292..93bbc87c9ab 100644
--- a/cypress/pageobject/Asset/AssetCreation.ts
+++ b/cypress/pageobject/Asset/AssetCreation.ts
@@ -285,16 +285,39 @@ export class AssetPage {
cy.get("#notes").scrollIntoView();
}
- enterAssetNotes(text) {
+ enterAssetNotes(text: string) {
cy.get("#notes").click().clear();
cy.get("#notes").click().type(text);
}
- enterAssetservicedate(text) {
+ enterAssetservicedate(text: string) {
cy.get("input[name='last_serviced_on']").click();
cy.get("#date-input").click().type(text);
}
+ scrollintoWarrantyDetails() {
+ cy.get("#warranty-details").scrollIntoView();
+ }
+
+ enterWarrantyExpiryDate(text: string) {
+ cy.get("#WarrantyAMCExpiry").click();
+ cy.get("#WarrantyAMCExpiry").click().type(text);
+ }
+
+ verifyWarrantyExpiryLabel(duration: string) {
+ if (duration === "") {
+ cy.get("#warranty-amc-expired-red").should("not.exist");
+ cy.get("#warranty-amc-expiring-soon-orange").should("not.exist");
+ cy.get("#warranty-amc-expiring-soon-yellow").should("not.exist");
+ } else if (duration === "expired") {
+ cy.get("#warranty-amc-expired-red").should("be.visible");
+ } else if (duration === "1 month") {
+ cy.get("#warranty-amc-expiring-soon-orange").should("be.visible");
+ } else if (duration === "3 months") {
+ cy.get("#warranty-amc-expiring-soon-yellow").should("be.visible");
+ }
+ }
+
clickassetupdatebutton() {
cy.get("#submit").click();
}
diff --git a/src/CAREUI/display/Chip.tsx b/src/CAREUI/display/Chip.tsx
index abc21711551..7bcbd6078e4 100644
--- a/src/CAREUI/display/Chip.tsx
+++ b/src/CAREUI/display/Chip.tsx
@@ -11,6 +11,7 @@ interface Props {
text: string;
tooltip?: string;
className?: string;
+ id?: string;
}
export default function Chip({
@@ -21,6 +22,7 @@ export default function Chip({
}: Props) {
return (
Date: Tue, 17 Oct 2023 06:34:39 +0530
Subject: [PATCH 5/5] Replaced export button Icon with relevant Export Icon
(#6451)
---
src/Components/Common/Export.tsx | 2 +-
src/Components/Patient/ManagePatients.tsx | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Components/Common/Export.tsx b/src/Components/Common/Export.tsx
index 3595b3c84a0..f991c476aac 100644
--- a/src/Components/Common/Export.tsx
+++ b/src/Components/Common/Export.tsx
@@ -44,7 +44,7 @@ export const ExportMenu = ({
}
+ icon={}
className="tooltip border-primary-500 bg-white text-primary-500 hover:bg-primary-100 enabled:border"
>
{exportItems.map((item) => (
diff --git a/src/Components/Patient/ManagePatients.tsx b/src/Components/Patient/ManagePatients.tsx
index 6e83eb9bc91..aa3a837647d 100644
--- a/src/Components/Patient/ManagePatients.tsx
+++ b/src/Components/Patient/ManagePatients.tsx
@@ -815,7 +815,7 @@ export const PatientManager = () => {
}}
className="mr-5 w-full lg:w-fit"
>
-
+
Export
) : (
|