From 9e8fd7a36f8e0619f814b7924f6a023be444d3d4 Mon Sep 17 00:00:00 2001 From: vivek Date: Sun, 1 Oct 2023 23:06:14 +0530 Subject: [PATCH 01/10] replaced dispatch with useQuery in ResultList --- src/Components/ExternalResult/ResultList.tsx | 42 ++++++++++---------- src/Components/ExternalResult/types.ts | 19 +++++++++ src/Redux/api.tsx | 3 ++ 3 files changed, 43 insertions(+), 21 deletions(-) create mode 100644 src/Components/ExternalResult/types.ts diff --git a/src/Components/ExternalResult/ResultList.tsx b/src/Components/ExternalResult/ResultList.tsx index 74fbf8430b0..18e2990e366 100644 --- a/src/Components/ExternalResult/ResultList.tsx +++ b/src/Components/ExternalResult/ResultList.tsx @@ -1,7 +1,6 @@ import ButtonV2 from "../Common/components/ButtonV2"; import { navigate } from "raviger"; import { lazy, useEffect, useState } from "react"; -import { useDispatch } from "react-redux"; import { externalResultList } from "../../Redux/actions"; import ListFilter from "./ListFilter"; import FacilitiesSelectDialogue from "./FacilitiesSelectDialogue"; @@ -15,12 +14,14 @@ 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 { IExternalResult } from "./types"; const Loading = lazy(() => import("../Common/Loading")); export default function ResultList() { - const dispatch: any = useDispatch(); - const [data, setData] = useState([]); + const [resultListData, setResultListData] = useState([]); const [isLoading, setIsLoading] = useState(false); const [totalCount, setTotalCount] = useState(0); const { @@ -57,7 +58,7 @@ export default function ResultList() { setPhoneNumberError("Enter a valid number"); }; - + const { res, data, loading } = useQuery(routes.externalResultList); let manageResults: any = null; useEffect(() => { setIsLoading(true); @@ -81,23 +82,21 @@ export default function ResultList() { 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); - }); + if (loading) { + setIsLoading(true); + } else if (res && data) { + setResultListData(data.results); + setTotalCount(data.count); + setIsLoading(false); + } if (!params.mobile_number) { setPhoneNum("+91"); } }, [ - dispatch, + res, + data, + loading, qParams.name, qParams.page, qParams.mobile_number, @@ -158,8 +157,8 @@ export default function ResultList() { }; let resultList: any[] = []; - if (data && data.length) { - resultList = data.map((result: any) => { + if (data && resultListData.length) { + resultList = resultListData.map((result: any) => { const resultUrl = `/external_results/${result.id}`; return ( @@ -173,7 +172,7 @@ export default function ResultList() { className="group inline-flex space-x-2 text-sm leading-5" >

- {result.name} - {result.age} {result.age_in} + {`${result.name} hi`} - {result.age} {result.age_in}

@@ -222,9 +221,9 @@ export default function ResultList() { ); - } else if (data && data.length) { + } else if (data && resultListData.length) { manageResults = <>{resultList}; - } else if (data && data.length === 0) { + } else if (data && resultListData.length === 0) { manageResults = ( @@ -302,6 +301,7 @@ export default function ResultList() {
setPhoneNum(e.value)} diff --git a/src/Components/ExternalResult/types.ts b/src/Components/ExternalResult/types.ts new file mode 100644 index 00000000000..2db4f6dc689 --- /dev/null +++ b/src/Components/ExternalResult/types.ts @@ -0,0 +1,19 @@ +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; +} + +export interface IExternalResultList { + count: number; + results: IExternalResult[]; +} diff --git a/src/Redux/api.tsx b/src/Redux/api.tsx index 1aa06c7e1bc..598062d59f0 100644 --- a/src/Redux/api.tsx +++ b/src/Redux/api.tsx @@ -1,5 +1,6 @@ import { IConfig } from "../Common/hooks/useConfig"; import { AssetData } from "../Components/Assets/AssetTypes"; +import { IExternalResultList } from "../Components/ExternalResult/types"; import { LocationModel } from "../Components/Facility/models"; import { UserModel } from "../Components/Users/models"; import { PaginatedResponse } from "../Utils/request/types"; @@ -484,6 +485,8 @@ const routes = { // External Results externalResultList: { path: "/api/v1/external_result/", + method: "GET", + TRes: Type(), }, externalResult: { path: "/api/v1/external_result/{id}/", From c8368ed3f4163b190446227361e0fea9d3809728 Mon Sep 17 00:00:00 2001 From: vivek Date: Thu, 5 Oct 2023 13:05:36 +0530 Subject: [PATCH 02/10] replaced useDispatch with useQuery in listfilter --- src/Components/ExternalResult/ListFilter.tsx | 111 ++++++++-------- src/Components/ExternalResult/ResultItem.tsx | 117 +++++++++-------- src/Components/ExternalResult/ResultList.tsx | 8 +- .../ExternalResult/ResultUpdate.tsx | 121 ++++++++---------- src/Components/ExternalResult/models.ts | 85 ++++++++++++ src/Components/ExternalResult/types.ts | 19 --- src/Redux/actions.tsx | 11 -- src/Redux/api.tsx | 23 +++- 8 files changed, 282 insertions(+), 213 deletions(-) create mode 100644 src/Components/ExternalResult/models.ts delete mode 100644 src/Components/ExternalResult/types.ts diff --git a/src/Components/ExternalResult/ListFilter.tsx b/src/Components/ExternalResult/ListFilter.tsx index 91b75e535d2..d2651afcb3f 100644 --- a/src/Components/ExternalResult/ListFilter.tsx +++ b/src/Components/ExternalResult/ListFilter.tsx @@ -1,6 +1,4 @@ -import { useEffect, useState } from "react"; -import { getAllLocalBodyByDistrict } from "../../Redux/actions"; -import { useDispatch } from "react-redux"; +import { useState } from "react"; import useMergeState from "../../Common/hooks/useMergeState"; import { navigate } from "raviger"; import { useTranslation } from "react-i18next"; @@ -11,6 +9,9 @@ import DateRangeFormField from "../Form/FormFields/DateRangeFormField"; import dayjs from "dayjs"; import { dateQueryString } from "../../Utils/utils"; import useAuthUser from "../../Common/hooks/useAuthUser"; +import useQuery from "../../Utils/request/useQuery"; +import routes from "../../Redux/api"; +import Loading from "../Common/Loading"; const clearFilterState = { created_date_before: "", @@ -32,7 +33,6 @@ export default function ListFilter(props: any) { const [wards, setWards] = useState([]); const [selectedLsgs, setSelectedLsgs] = useState([]); - const dispatch: any = useDispatch(); const authUser = useAuthUser(); const [filterState, setFilterState] = useMergeState({ created_date_before: filter.created_date_before || null, @@ -45,6 +45,57 @@ export default function ListFilter(props: any) { }); const { t } = useTranslation(); + const { loading } = useQuery(routes.getAllLocalBodyByDistrict, { + pathParams: { id: String(authUser.district) }, + onResponse: ({ res, data }) => { + if (res && data) { + let allWards: any[] = []; + let allLsgs: any[] = []; + if (res && data) { + data.forEach((local: any) => { + allLsgs = [...allLsgs, { id: local.id, name: local.name }]; + if (local.wards) { + local.wards.forEach((ward: any) => { + allWards = [ + ...allWards, + { + id: ward.id, + name: ward.number + ": " + ward.name, + panchayath: local.name, + number: ward.number, + local_body_id: local.id, + }, + ]; + }); + } + }); + } + + sortByName(allWards); + sortByName(allLsgs); + setWardList(allWards || []); + setLsgList(allLsgs || []); + const filteredWard = filter?.wards?.split(",").map(Number); + const selectedWards: any = + filteredWard && allWards + ? allWards.filter(({ id }: { id: number }) => { + return filteredWard.includes(id); + }) + : []; + setWards(selectedWards); + + const filteredLsgs = filter?.local_bodies?.split(",").map(Number); + const selectedLsgs: any = + filteredLsgs && allLsgs + ? allLsgs.filter(({ id }: { id: number }) => { + return filteredLsgs.includes(id); + }) + : []; + setSelectedLsgs(selectedLsgs); + } + }, + }); + const handleDateRangeChange = ( startDateId: string, endDateId: string, @@ -118,54 +169,6 @@ export default function ListFilter(props: any) { }); }; - useEffect(() => { - async function getWardList() { - const id = authUser.district; - const res = await dispatch(getAllLocalBodyByDistrict({ id })); - let allWards: any[] = []; - let allLsgs: any[] = []; - res?.data?.forEach((local: any) => { - allLsgs = [...allLsgs, { id: local.id, name: local.name }]; - if (local.wards) { - local.wards.forEach((ward: any) => { - allWards = [ - ...allWards, - { - id: ward.id, - name: ward.number + ": " + ward.name, - panchayath: local.name, - number: ward.number, - local_body_id: local.id, - }, - ]; - }); - } - }); - sortByName(allWards); - sortByName(allLsgs); - setWardList(allWards || []); - setLsgList(allLsgs || []); - const filteredWard = filter?.wards?.split(",").map(Number); - const selectedWards: any = - filteredWard && allWards - ? allWards.filter(({ id }: { id: number }) => { - return filteredWard.includes(id); - }) - : []; - setWards(selectedWards); - - const filteredLsgs = filter?.local_bodies?.split(",").map(Number); - const selectedLsgs: any = - filteredLsgs && allLsgs - ? allLsgs.filter(({ id }: { id: number }) => { - return filteredLsgs.includes(id); - }) - : []; - setSelectedLsgs(selectedLsgs); - } - getWardList(); - }, []); - const filterWards = () => { const selectedLsgIds: any = selectedLsgs.map((e) => { return e.id; @@ -190,6 +193,10 @@ export default function ListFilter(props: any) { setFilterState(filterData); }; + if (loading) { + ; + } + return ( import("../Common/Loading")); export default function ResultItem(props: any) { - const dispatch: any = useDispatch(); const initialData: any = {}; - const [data, setData] = useState(initialData); + const [resultItemData, setResultItemData] = useState(initialData); const [isLoading, setIsLoading] = useState(true); const [showDeleteAlert, setShowDeleteAlert] = useState(false); const { t } = useTranslation(); - const fetchData = useCallback( - async (status: statusType) => { - setIsLoading(true); - const res = await dispatch(externalResult({ id: props.id })); - if (!status.aborted) { - if (res && res.data) { - setData(res.data); - } - setIsLoading(false); + useQuery(routes.externalResult, { + pathParams: { id: props.id }, + onResponse: ({ res, data }) => { + if (res?.status === 200 && data) { + setResultItemData(data); } + setIsLoading(false); }, - [props.id, dispatch] - ); + }); const handleDelete = async () => { - const res = await dispatch(deleteExternalResult(props.id)); - if (res?.status === 204) { - Notification.Success({ - msg: t("record_has_been_deleted_successfully"), - }); - } else { - Notification.Error({ - msg: - t("error_while_deleting_record") + ": " + (res?.data?.detail || ""), + console.log("handleDelete"); + if (showDeleteAlert) { + const { res, data } = await request(routes.deleteExternalResult, { + pathParams: { id: props.id }, }); - } - setShowDeleteAlert(false); - navigate("/external_results"); + if (res?.status === 204) { + Notification.Success({ + msg: t("record_has_been_deleted_successfully"), + }); + } else { + Notification.Error({ + msg: t("error_while_deleting_record") + ": " + (data?.detail || ""), + }); + } + setShowDeleteAlert(false); + navigate("/external_results"); + } }; - useAbortableEffect( - (status: statusType) => { - fetchData(status); - }, - [fetchData] - ); - if (isLoading) { return ; } @@ -69,14 +60,18 @@ export default function ResultItem(props: any) { variant="danger" action={t("delete")} show={showDeleteAlert} - onConfirm={() => handleDelete()} + onConfirm={() => { + handleDelete(); + }} onClose={() => setShowDeleteAlert(false)} />
diff --git a/src/Components/ExternalResult/ResultList.tsx b/src/Components/ExternalResult/ResultList.tsx index 18e2990e366..c108ace8a9b 100644 --- a/src/Components/ExternalResult/ResultList.tsx +++ b/src/Components/ExternalResult/ResultList.tsx @@ -16,12 +16,14 @@ import { AdvancedFilterButton } from "../../CAREUI/interactive/FiltersSlideover" import Page from "../Common/components/Page"; import routes from "../../Redux/api"; import useQuery from "../../Utils/request/useQuery"; -import { IExternalResult } from "./types"; +import { IExternalResult } from "./models"; const Loading = lazy(() => import("../Common/Loading")); export default function ResultList() { - const [resultListData, setResultListData] = useState([]); + const [resultListData, setResultListData] = useState< + Partial[] + >([]); const [isLoading, setIsLoading] = useState(false); const [totalCount, setTotalCount] = useState(0); const { @@ -172,7 +174,7 @@ export default function ResultList() { className="group inline-flex space-x-2 text-sm leading-5" >

- {`${result.name} hi`} - {result.age} {result.age_in} + {`${result.name}`} - {result.age} {result.age_in}

diff --git a/src/Components/ExternalResult/ResultUpdate.tsx b/src/Components/ExternalResult/ResultUpdate.tsx index dd99c480da5..92d4d63b427 100644 --- a/src/Components/ExternalResult/ResultUpdate.tsx +++ b/src/Components/ExternalResult/ResultUpdate.tsx @@ -1,14 +1,5 @@ import { useCallback, useState, useReducer, lazy } from "react"; - import * as Notification from "../../Utils/Notifications.js"; -import { useDispatch } from "react-redux"; -import { statusType, useAbortableEffect } from "../../Common/utils"; -import { - getLocalbodyByDistrict, - getWardByLocalBody, - externalResult, - partialUpdateExternalResult, -} from "../../Redux/actions"; import TextAreaFormField from "../Form/FormFields/TextAreaFormField.js"; import CircularProgress from "../Common/components/CircularProgress.js"; import { SelectFormField } from "../Form/FormFields/SelectFormField.js"; @@ -17,6 +8,9 @@ import { navigate } from "raviger"; import { Cancel, Submit } from "../Common/components/ButtonV2"; import useAppHistory from "../../Common/hooks/useAppHistory"; import Page from "../Common/components/Page.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")); @@ -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..82c91b08e3e --- /dev/null +++ b/src/Components/ExternalResult/models.ts @@ -0,0 +1,85 @@ +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 IExternalResultList { + count: number; + results: Partial[]; +} + +export interface IDeleteExternalResult { + detail: string; +} + +export interface Ward { + id: number; + name: string; + number: number; + local_body: number; +} + +export interface IWardByLocalBody { + count: number; + results: Ward[]; +} + +export interface IPartialUpdateExternalResult { + address: string; + ward: number; + local_body: number; + patient_created: boolean; +} + +export interface ILocalBodyByDistrict { + id: number; + name: string; + state: number; +} diff --git a/src/Components/ExternalResult/types.ts b/src/Components/ExternalResult/types.ts deleted file mode 100644 index 2db4f6dc689..00000000000 --- a/src/Components/ExternalResult/types.ts +++ /dev/null @@ -1,19 +0,0 @@ -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; -} - -export interface IExternalResultList { - count: number; - results: IExternalResult[]; -} diff --git a/src/Redux/actions.tsx b/src/Redux/actions.tsx index 1a5bd7e4fb1..a41014ccb30 100644 --- a/src/Redux/actions.tsx +++ b/src/Redux/actions.tsx @@ -472,10 +472,6 @@ export const getWards = (params: object) => { return fireRequest("getWards", [], params); }; -export const getAllLocalBodyByDistrict = (pathParam: object) => { - return fireRequest("getAllLocalBodyByDistrict", [], {}, pathParam); -}; - // Local Body export const getLocalBody = (pathParam: object) => { return fireRequest("getLocalBody", [], {}, pathParam); @@ -665,17 +661,10 @@ export const externalResultList = (params: object, altKey: string) => { return fireRequest("externalResultList", [], params, null, altKey); }; -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 598062d59f0..32380a52eb2 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 { IExternalResultList } from "../Components/ExternalResult/types"; +import { + IDeleteExternalResult, + IExternalResult, + IExternalResultList, + ILocalBodies, + ILocalBodyByDistrict, + IPartialUpdateExternalResult, + IWardByLocalBody, +} from "../Components/ExternalResult/models"; import { LocationModel } from "../Components/Facility/models"; import { UserModel } from "../Components/Users/models"; import { PaginatedResponse } from "../Utils/request/types"; @@ -490,6 +498,8 @@ const routes = { }, externalResult: { path: "/api/v1/external_result/{id}/", + method: "GET", + TRes: Type(), }, externalResultUploadCsv: { path: "/api/v1/external_result/bulk_upsert/", @@ -497,8 +507,9 @@ const routes = { }, deleteExternalResult: { - path: "/api/v1/external_result", + path: "/api/v1/external_result/{id}/", method: "DELETE", + TRes: Type(), }, updateExternalResult: { @@ -509,6 +520,8 @@ const routes = { partialUpdateExternalResult: { path: "/api/v1/external_result/{id}/", method: "PATCH", + TRes: Type(), + TBody: Type(), }, // States @@ -533,9 +546,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 @@ -558,6 +575,8 @@ const routes = { }, getWardByLocalBody: { path: "/api/v1/ward/?local_body={id}", + method: "GET", + TRes: Type(), }, // Sample Test From de8a84f4481ded7e8917b57090488127d2dcd7b8 Mon Sep 17 00:00:00 2001 From: vivek Date: Thu, 5 Oct 2023 15:35:13 +0530 Subject: [PATCH 03/10] replaced useDispatch with reqeust in ExternalResultUpload --- .../ExternalResult/ExternalResultUpload.tsx | 35 ++++++++++++------- src/Components/ExternalResult/models.ts | 4 +++ src/Redux/actions.tsx | 4 +-- src/Redux/api.tsx | 3 ++ 4 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/Components/ExternalResult/ExternalResultUpload.tsx b/src/Components/ExternalResult/ExternalResultUpload.tsx index 5f39cb213a4..a9d5c29bfe8 100644 --- a/src/Components/ExternalResult/ExternalResultUpload.tsx +++ b/src/Components/ExternalResult/ExternalResultUpload.tsx @@ -2,21 +2,21 @@ import _ from "lodash"; import { navigate } from "raviger"; import { lazy, useState } from "react"; import CSVReader from "react-csv-reader"; -import { useDispatch } from "react-redux"; import useConfig from "../../Common/hooks/useConfig"; -import { externalResultUploadCsv } from "../../Redux/actions"; import * as Notification from "../../Utils/Notifications.js"; const PageTitle = lazy(() => import("../Common/PageTitle")); import { useTranslation } from "react-i18next"; import { Cancel, Submit } from "../Common/components/ButtonV2"; import useAppHistory from "../../Common/hooks/useAppHistory"; +import request from "../../Utils/request/request"; +import routes from "../../Redux/api"; +import { IExternalResult } from "./models"; export default function ExternalResultUpload() { const { sample_format_external_result_import } = useConfig(); - const dispatch: any = useDispatch(); // for disabling save button once clicked const [loading, setLoading] = useState(false); - const [csvData, setCsvData] = useState(new Array()); + const [csvData, setCsvData] = useState(new Array()); const [errors, setErrors] = useState([]); const handleForce = (data: any) => { setCsvData(data); @@ -32,26 +32,35 @@ export default function ExternalResultUpload() { header.toLowerCase().replace(/\W/g, "_"), }; - const handleSubmit = (e: any) => { + const handleSubmit = async (e: any) => { e.preventDefault(); setLoading(true); const valid = true; - if (csvData.length !== 0) { - const data = { - sample_tests: csvData, - }; + if (csvData.length !== 0) { if (valid) { setErrors([]); - dispatch(externalResultUploadCsv(data)).then((resp: any) => { - if (resp && resp.status === 202) { + + try { + const { res, data } = await request(routes.externalResultUploadCsv, { + body: { + sample_tests: csvData, + }, + }); + + if (res && res.status === 202) { setLoading(false); navigate("/external_results"); } else { - setErrors(resp.data.map((err: any) => Object.entries(err))); + if (data) { + setErrors(data.map((err: any) => Object.entries(err))); + } setLoading(false); } - }); + } catch (error) { + console.error("An error occurred:", error); + setLoading(false); + } } else { setLoading(false); } diff --git a/src/Components/ExternalResult/models.ts b/src/Components/ExternalResult/models.ts index 82c91b08e3e..163e3400f34 100644 --- a/src/Components/ExternalResult/models.ts +++ b/src/Components/ExternalResult/models.ts @@ -83,3 +83,7 @@ export interface ILocalBodyByDistrict { name: string; state: number; } + +export interface IExternalResultCsv { + sample_tests: Partial[]; +} diff --git a/src/Redux/actions.tsx b/src/Redux/actions.tsx index a41014ccb30..caf46469cc7 100644 --- a/src/Redux/actions.tsx +++ b/src/Redux/actions.tsx @@ -661,8 +661,8 @@ export const externalResultList = (params: object, altKey: string) => { return fireRequest("externalResultList", [], params, null, altKey); }; -export const externalResultUploadCsv = (params: object) => { - return fireRequest("externalResultUploadCsv", [], params); +export const externalResult = (pathParam: object) => { + return fireRequest("externalResult", [], {}, pathParam); }; export const updateExternalResult = (id: number, params: object) => { diff --git a/src/Redux/api.tsx b/src/Redux/api.tsx index 32380a52eb2..2dc7fbb574a 100644 --- a/src/Redux/api.tsx +++ b/src/Redux/api.tsx @@ -3,6 +3,7 @@ import { AssetData } from "../Components/Assets/AssetTypes"; import { IDeleteExternalResult, IExternalResult, + IExternalResultCsv, IExternalResultList, ILocalBodies, ILocalBodyByDistrict, @@ -504,6 +505,8 @@ const routes = { externalResultUploadCsv: { path: "/api/v1/external_result/bulk_upsert/", method: "POST", + TBody: Type(), + TRes: Type(), }, deleteExternalResult: { From 1ab65b7818c8f534837652977b5d5db55c8bdb60 Mon Sep 17 00:00:00 2001 From: vivek Date: Fri, 6 Oct 2023 16:09:53 +0530 Subject: [PATCH 04/10] fixed filtering --- src/Components/ExternalResult/ListFilter.tsx | 3 ++ src/Components/ExternalResult/ResultItem.tsx | 1 - src/Components/ExternalResult/ResultList.tsx | 46 ++++++++++++-------- src/Components/ExternalResult/models.ts | 17 -------- src/Redux/actions.tsx | 4 ++ src/Redux/api.tsx | 8 ++-- src/Utils/request/request.ts | 29 +++++++++--- 7 files changed, 62 insertions(+), 46 deletions(-) diff --git a/src/Components/ExternalResult/ListFilter.tsx b/src/Components/ExternalResult/ListFilter.tsx index d2651afcb3f..ca0fcabfad1 100644 --- a/src/Components/ExternalResult/ListFilter.tsx +++ b/src/Components/ExternalResult/ListFilter.tsx @@ -161,6 +161,9 @@ export default function ListFilter(props: any) { }; onChange(data); dataList(selectedLsgs, wards); + console.log("data", data); + console.log("selectedLsgs", selectedLsgs); + console.log("wards", wards); }; const sortByName = (items: any) => { diff --git a/src/Components/ExternalResult/ResultItem.tsx b/src/Components/ExternalResult/ResultItem.tsx index a98026b5b08..ec24273c114 100644 --- a/src/Components/ExternalResult/ResultItem.tsx +++ b/src/Components/ExternalResult/ResultItem.tsx @@ -28,7 +28,6 @@ export default function ResultItem(props: any) { }); const handleDelete = async () => { - console.log("handleDelete"); if (showDeleteAlert) { const { res, data } = await request(routes.deleteExternalResult, { pathParams: { id: props.id }, diff --git a/src/Components/ExternalResult/ResultList.tsx b/src/Components/ExternalResult/ResultList.tsx index c108ace8a9b..1e8b5ace74e 100644 --- a/src/Components/ExternalResult/ResultList.tsx +++ b/src/Components/ExternalResult/ResultList.tsx @@ -17,6 +17,7 @@ import Page from "../Common/components/Page"; import routes from "../../Redux/api"; import useQuery from "../../Utils/request/useQuery"; import { IExternalResult } from "./models"; +import request from "../../Utils/request/request"; const Loading = lazy(() => import("../Common/Loading")); @@ -24,7 +25,7 @@ export default function ResultList() { const [resultListData, setResultListData] = useState< Partial[] >([]); - const [isLoading, setIsLoading] = useState(false); + const [isLoading, setIsLoading] = useState(true); const [totalCount, setTotalCount] = useState(0); const { qParams, @@ -60,7 +61,17 @@ export default function ResultList() { setPhoneNumberError("Enter a valid number"); }; - const { res, data, loading } = useQuery(routes.externalResultList); + + useQuery(routes.externalResultList, { + onResponse: ({ res, data }) => { + if (res && data) { + setResultListData(data.results); + setTotalCount(data.count); + setIsLoading(false); + } + }, + }); + let manageResults: any = null; useEffect(() => { setIsLoading(true); @@ -80,25 +91,26 @@ export default function ResultList() { qParams.sample_collection_date_after || undefined, sample_collection_date_before: qParams.sample_collection_date_before || undefined, - offset: (qParams.page ? qParams.page - 1 : 0) * resultsPerPage, + offset: String((qParams.page ? qParams.page - 1 : 0) * resultsPerPage), srf_id: qParams.srf_id || undefined, }; - if (loading) { - setIsLoading(true); - } else if (res && data) { - setResultListData(data.results); - setTotalCount(data.count); - setIsLoading(false); - } + const fetchData = async () => { + const { res, data } = await request(routes.externalResultList, { + query: params, + }); + if (res && data) { + setResultListData(data.results); + setTotalCount(data.count); + setIsLoading(false); + } + }; + fetchData(); if (!params.mobile_number) { setPhoneNum("+91"); } }, [ - res, - data, - loading, qParams.name, qParams.page, qParams.mobile_number, @@ -159,7 +171,7 @@ export default function ResultList() { }; let resultList: any[] = []; - if (data && resultListData.length) { + if (resultListData.length) { resultList = resultListData.map((result: any) => { const resultUrl = `/external_results/${result.id}`; return ( @@ -215,7 +227,7 @@ export default function ResultList() { }); } - if (isLoading || !data) { + if (isLoading) { manageResults = ( @@ -223,9 +235,9 @@ export default function ResultList() { ); - } else if (data && resultListData.length) { + } else if (resultListData.length) { manageResults = <>{resultList}; - } else if (data && resultListData.length === 0) { + } else if (resultListData.length === 0) { manageResults = ( diff --git a/src/Components/ExternalResult/models.ts b/src/Components/ExternalResult/models.ts index 163e3400f34..8ccaba04d05 100644 --- a/src/Components/ExternalResult/models.ts +++ b/src/Components/ExternalResult/models.ts @@ -50,27 +50,10 @@ export interface ILocalBodies { district: number; } -export interface IExternalResultList { - count: number; - results: Partial[]; -} - export interface IDeleteExternalResult { detail: string; } -export interface Ward { - id: number; - name: string; - number: number; - local_body: number; -} - -export interface IWardByLocalBody { - count: number; - results: Ward[]; -} - export interface IPartialUpdateExternalResult { address: string; ward: number; diff --git a/src/Redux/actions.tsx b/src/Redux/actions.tsx index 3257ab1fa3e..06a12796737 100644 --- a/src/Redux/actions.tsx +++ b/src/Redux/actions.tsx @@ -472,6 +472,10 @@ export const getWards = (params: object) => { return fireRequest("getWards", [], params); }; +export const getAllLocalBodyByDistrict = (pathParam: object) => { + return fireRequest("getAllLocalBodyByDistrict", [], {}, pathParam); +}; + // Local Body export const getLocalBody = (pathParam: object) => { return fireRequest("getLocalBody", [], {}, pathParam); diff --git a/src/Redux/api.tsx b/src/Redux/api.tsx index e4ceaa74a6a..60ca3c2906b 100644 --- a/src/Redux/api.tsx +++ b/src/Redux/api.tsx @@ -4,13 +4,11 @@ import { IDeleteExternalResult, IExternalResult, IExternalResultCsv, - IExternalResultList, ILocalBodies, ILocalBodyByDistrict, IPartialUpdateExternalResult, - IWardByLocalBody, } from "../Components/ExternalResult/models"; -import { LocationModel } from "../Components/Facility/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"; @@ -509,7 +507,7 @@ const routes = { externalResultList: { path: "/api/v1/external_result/", method: "GET", - TRes: Type(), + TRes: Type>(), }, externalResult: { path: "/api/v1/external_result/{id}/", @@ -593,7 +591,7 @@ const routes = { getWardByLocalBody: { path: "/api/v1/ward/?local_body={id}", method: "GET", - TRes: Type(), + TRes: Type>(), }, // Sample Test diff --git a/src/Utils/request/request.ts b/src/Utils/request/request.ts index 2d735734aae..a2adad1bd45 100644 --- a/src/Utils/request/request.ts +++ b/src/Utils/request/request.ts @@ -38,13 +38,30 @@ export default async function request( try { const res = await fetch(url, options); - const data: TData = await res.json(); - result = { - res, - data: res.ok ? data : undefined, - error: res.ok ? undefined : (data as Record), - }; + if (!res.ok) { + const data: Record = await res.json(); + result = { + res, + data: undefined, + error: data, + }; + } else if ( + res.headers.get("content-type")?.includes("application/json") + ) { + const data: TData = await res.json(); + result = { + res, + data, + error: undefined, + }; + } else { + result = { + res, + data: undefined, + error: undefined, + }; + } onResponse?.(result); handleResponse(result, silent); From 1429b1c5f362d4a9de0819cad7303781470dfa14 Mon Sep 17 00:00:00 2001 From: vivek Date: Fri, 6 Oct 2023 18:48:11 +0530 Subject: [PATCH 05/10] rm clg --- src/Components/ExternalResult/ListFilter.tsx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/Components/ExternalResult/ListFilter.tsx b/src/Components/ExternalResult/ListFilter.tsx index ca0fcabfad1..75358196ffd 100644 --- a/src/Components/ExternalResult/ListFilter.tsx +++ b/src/Components/ExternalResult/ListFilter.tsx @@ -30,7 +30,6 @@ export default function ListFilter(props: any) { const { filter, onChange, closeFilter, dataList } = props; const [wardList, setWardList] = useState([]); const [lsgList, setLsgList] = useState([]); - const [wards, setWards] = useState([]); const [selectedLsgs, setSelectedLsgs] = useState([]); const authUser = useAuthUser(); @@ -161,9 +160,6 @@ export default function ListFilter(props: any) { }; onChange(data); dataList(selectedLsgs, wards); - console.log("data", data); - console.log("selectedLsgs", selectedLsgs); - console.log("wards", wards); }; const sortByName = (items: any) => { @@ -176,7 +172,6 @@ export default function ListFilter(props: any) { const selectedLsgIds: any = selectedLsgs.map((e) => { return e.id; }); - const selectedwards: any = selectedLsgIds.length === 0 ? wardList @@ -189,10 +184,8 @@ export default function ListFilter(props: any) { const handleChange = (event: any) => { const { name, value } = event.target; - const filterData: any = { ...filterState }; filterData[name] = value; - setFilterState(filterData); }; From 905780e4c1f25e4cb4dc86320df7f67b69c8be4e Mon Sep 17 00:00:00 2001 From: vivek Date: Sun, 8 Oct 2023 19:41:22 +0530 Subject: [PATCH 06/10] fix ResultList --- src/Components/ExternalResult/ResultList.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Components/ExternalResult/ResultList.tsx b/src/Components/ExternalResult/ResultList.tsx index 1e8b5ace74e..d4247b99a2f 100644 --- a/src/Components/ExternalResult/ResultList.tsx +++ b/src/Components/ExternalResult/ResultList.tsx @@ -315,7 +315,6 @@ export default function ResultList() {
setPhoneNum(e.value)} From 29fec55ebfe9c1219fbd765a5cbd2f00bfde0a53 Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Mon, 9 Oct 2023 18:36:14 +0530 Subject: [PATCH 07/10] make code readable --- src/Utils/request/request.ts | 47 ++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/Utils/request/request.ts b/src/Utils/request/request.ts index a2adad1bd45..72df402ef1a 100644 --- a/src/Utils/request/request.ts +++ b/src/Utils/request/request.ts @@ -38,30 +38,13 @@ export default async function request( try { const res = await fetch(url, options); + const data = await getResponseBody(res); - if (!res.ok) { - const data: Record = await res.json(); - result = { - res, - data: undefined, - error: data, - }; - } else if ( - res.headers.get("content-type")?.includes("application/json") - ) { - const data: TData = await res.json(); - result = { - res, - data, - error: undefined, - }; - } else { - result = { - res, - data: undefined, - error: undefined, - }; - } + result = { + res, + data: res.ok ? data : undefined, + error: res.ok ? undefined : (data as Record), + }; onResponse?.(result); handleResponse(result, silent); @@ -78,3 +61,21 @@ export default async function request( ); return result; } + +const getResponseBody = async (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 5d8eeabc72b10cba009deb560546dfc03e56d9e3 Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Mon, 9 Oct 2023 18:39:35 +0530 Subject: [PATCH 08/10] fix build --- src/Utils/request/request.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Utils/request/request.ts b/src/Utils/request/request.ts index 72df402ef1a..d428107b64c 100644 --- a/src/Utils/request/request.ts +++ b/src/Utils/request/request.ts @@ -62,7 +62,7 @@ export default async function request( return result; } -const getResponseBody = async (res: Response): Promise => { +async function getResponseBody(res: Response): Promise { if (!(res.headers.get("content-length") !== "0")) { return null as TData; } @@ -78,4 +78,4 @@ const getResponseBody = async (res: Response): Promise => { } catch { return (await res.text()) as TData; } -}; +} From 0a683a40094c86e740a214f5cbe5bd1f51c482b8 Mon Sep 17 00:00:00 2001 From: vivek Date: Tue, 10 Oct 2023 12:42:05 +0530 Subject: [PATCH 09/10] removed useEffect and useState from ResultList.tsx --- src/Components/ExternalResult/ResultList.tsx | 109 ++++++------------- 1 file changed, 31 insertions(+), 78 deletions(-) diff --git a/src/Components/ExternalResult/ResultList.tsx b/src/Components/ExternalResult/ResultList.tsx index d4247b99a2f..d148b26e3f5 100644 --- a/src/Components/ExternalResult/ResultList.tsx +++ b/src/Components/ExternalResult/ResultList.tsx @@ -1,11 +1,10 @@ import ButtonV2 from "../Common/components/ButtonV2"; import { navigate } from "raviger"; -import { lazy, useEffect, useState } from "react"; +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"; @@ -16,17 +15,10 @@ import { AdvancedFilterButton } from "../../CAREUI/interactive/FiltersSlideover" import Page from "../Common/components/Page"; import routes from "../../Redux/api"; import useQuery from "../../Utils/request/useQuery"; -import { IExternalResult } from "./models"; -import request from "../../Utils/request/request"; - +import { parsePhoneNumber } from "../../Utils/utils"; const Loading = lazy(() => import("../Common/Loading")); export default function ResultList() { - const [resultListData, setResultListData] = useState< - Partial[] - >([]); - const [isLoading, setIsLoading] = useState(true); - const [totalCount, setTotalCount] = useState(0); const { qParams, updateQuery, @@ -61,70 +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, + }; - useQuery(routes.externalResultList, { - onResponse: ({ res, data }) => { - if (res && data) { - setResultListData(data.results); - setTotalCount(data.count); - setIsLoading(false); - } - }, + const { data, loading } = useQuery(routes.externalResultList, { + query: params, }); 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: String((qParams.page ? qParams.page - 1 : 0) * resultsPerPage), - srf_id: qParams.srf_id || undefined, - }; - - const fetchData = async () => { - const { res, data } = await request(routes.externalResultList, { - query: params, - }); - if (res && data) { - setResultListData(data.results); - setTotalCount(data.count); - setIsLoading(false); - } - }; - fetchData(); - - if (!params.mobile_number) { - setPhoneNum("+91"); - } - }, [ - 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, - ]); const removeLSGFilter = (paramKey: any, id: any) => { const updatedLsgList = dataList.lsgList.filter((x: any) => x.id !== id); @@ -171,8 +124,8 @@ export default function ResultList() { }; let resultList: any[] = []; - if (resultListData.length) { - resultList = resultListData.map((result: any) => { + if (data?.results.length) { + resultList = data.results.map((result: any) => { const resultUrl = `/external_results/${result.id}`; return ( @@ -227,7 +180,7 @@ export default function ResultList() { }); } - if (isLoading) { + if (loading) { manageResults = ( @@ -235,9 +188,9 @@ export default function ResultList() { ); - } else if (resultListData.length) { + } else if (data?.results.length) { manageResults = <>{resultList}; - } else if (resultListData.length === 0) { + } else if (data?.results.length === 0) { manageResults = ( @@ -299,8 +252,8 @@ export default function ResultList() {
@@ -371,7 +324,7 @@ export default function ResultList() {
- + Date: Wed, 11 Oct 2023 10:36:01 +0530 Subject: [PATCH 10/10] Apply changes from code review --- src/Components/ExternalResult/ResultItem.tsx | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/Components/ExternalResult/ResultItem.tsx b/src/Components/ExternalResult/ResultItem.tsx index ec24273c114..47363e02ce1 100644 --- a/src/Components/ExternalResult/ResultItem.tsx +++ b/src/Components/ExternalResult/ResultItem.tsx @@ -11,20 +11,11 @@ import request from "../../Utils/request/request"; const Loading = lazy(() => import("../Common/Loading")); export default function ResultItem(props: any) { - const initialData: any = {}; - const [resultItemData, setResultItemData] = useState(initialData); - const [isLoading, setIsLoading] = useState(true); const [showDeleteAlert, setShowDeleteAlert] = useState(false); const { t } = useTranslation(); - useQuery(routes.externalResult, { + const { data: resultItemData, loading } = useQuery(routes.externalResult, { pathParams: { id: props.id }, - onResponse: ({ res, data }) => { - if (res?.status === 200 && data) { - setResultItemData(data); - } - setIsLoading(false); - }, }); const handleDelete = async () => { @@ -47,7 +38,7 @@ export default function ResultItem(props: any) { } }; - if (isLoading) { + if (loading || !resultItemData) { return ; }