From 7236eeeea55954456ddae8337c6ce81336c04eea Mon Sep 17 00:00:00 2001 From: rajku-dev Date: Wed, 29 Jan 2025 09:39:50 +0530 Subject: [PATCH 1/8] show placeholder page data | add stale time | fix translations --- public/locale/en.json | 2 + src/components/Facility/FacilityUsers.tsx | 4 +- src/components/Files/FilesTab.tsx | 5 ++- src/components/Resource/ResourceList.tsx | 44 +++++++++++-------- src/pages/Encounters/EncounterList.tsx | 4 +- src/pages/Facility/FacilitiesPage.tsx | 4 +- src/pages/Facility/FacilityDetailsPage.tsx | 4 +- .../Organization/OrganizationFacilities.tsx | 4 +- .../Organization/OrganizationPatients.tsx | 4 +- 9 files changed, 50 insertions(+), 25 deletions(-) diff --git a/public/locale/en.json b/public/locale/en.json index 9aa895900a3..18b6cb130db 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -577,6 +577,7 @@ "confirm_transfer_complete": "Confirm Transfer Complete!", "confirm_unavailability": "Confirm Unavailability", "confirmed": "Confirmed", + "consent_status": "Consent Status", "consult": "Consult", "consultation_history": "Consultation History", "consultation_missing_warning": "You have not created a consultation for the patient in", @@ -921,6 +922,7 @@ "error_fetching_slots_data": "Error while fetching slots data", "error_fetching_user_data": "Error while fetching user data", "error_fetching_user_details": "Error while fetching user details: ", + "error_fetching_users_data": "Error fetching users data", "error_loading_questionnaire_response": "Error loading questionnaire response", "error_sending_otp": "Error while sending OTP, Please try again later", "error_updating_encounter": "Error to Updating Encounter", diff --git a/src/components/Facility/FacilityUsers.tsx b/src/components/Facility/FacilityUsers.tsx index 288feaa187e..d2d855d8859 100644 --- a/src/components/Facility/FacilityUsers.tsx +++ b/src/components/Facility/FacilityUsers.tsx @@ -1,4 +1,4 @@ -import { useQuery } from "@tanstack/react-query"; +import { keepPreviousData, useQuery } from "@tanstack/react-query"; import { useTranslation } from "react-i18next"; import CareIcon from "@/CAREUI/icons/CareIcon"; @@ -43,6 +43,8 @@ export default function FacilityUsers(props: { facilityId: string }) { }, }), enabled: !!facilityId, + placeholderData: keepPreviousData, + staleTime: 1000 * 60, }); if (userListLoading || !userListData) { diff --git a/src/components/Files/FilesTab.tsx b/src/components/Files/FilesTab.tsx index 703366a1893..03981fed09f 100644 --- a/src/components/Files/FilesTab.tsx +++ b/src/components/Files/FilesTab.tsx @@ -1,4 +1,4 @@ -import { useQuery } from "@tanstack/react-query"; +import { keepPreviousData, useQuery } from "@tanstack/react-query"; import dayjs from "dayjs"; import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -108,6 +108,9 @@ export const FilesTab = (props: FilesTabProps) => { //file_category: qParams.file_category, }, }), + enabled: !!type, + placeholderData: keepPreviousData, + staleTime: 1000 * 60 * 5, }); const fileManager = useFileManager({ diff --git a/src/components/Resource/ResourceList.tsx b/src/components/Resource/ResourceList.tsx index a754455b772..2d78a891904 100644 --- a/src/components/Resource/ResourceList.tsx +++ b/src/components/Resource/ResourceList.tsx @@ -1,3 +1,4 @@ +import { keepPreviousData, useQuery } from "@tanstack/react-query"; import { Link } from "raviger"; import { useTranslation } from "react-i18next"; @@ -18,8 +19,7 @@ import ListFilter from "@/components/Resource/ResourceFilter"; import useFilters from "@/hooks/useFilters"; import routes from "@/Utils/request/api"; -import request from "@/Utils/request/request"; -import useTanStackQueryInstead from "@/Utils/request/useQuery"; +import query from "@/Utils/request/query"; import { useView } from "@/Utils/useView"; import { formatDateTime } from "@/Utils/utils"; import { ResourceRequest } from "@/types/resourceRequest/resourceRequest"; @@ -39,16 +39,29 @@ export default function ListView() { const appliedFilters = formatFilter(qParams); - const { loading, data, refetch } = useTanStackQueryInstead( - routes.listResourceRequests, - { - query: formatFilter({ + const { + data: resourcesList, + isLoading: loading, + refetch: refetchResources, + } = useQuery({ + queryKey: ["resourceRequests", qParams], + queryFn: query.debounced(routes.listResourceRequests, { + queryParams: formatFilter({ ...qParams, limit: resultsPerPage, offset: (qParams.page ? qParams.page - 1 : 0) * resultsPerPage, }), - }, - ); + }), + placeholderData: keepPreviousData, + staleTime: 1000 * 60 * 2, + }); + + const { data: csvFile } = useQuery({ + queryKey: ["downloadResourcesCsv", appliedFilters], + queryFn: query(routes.downloadResourceRequests, { + queryParams: { ...appliedFilters, csv: true }, + }), + }); const showResourceCardList = (data: ResourceRequest[]) => { if (data && !data.length) { @@ -197,12 +210,7 @@ export default function ListView() { { - const { data } = await request(routes.downloadResourceRequests, { - query: { ...appliedFilters, csv: true }, - }); - return data ?? null; - }} + action={async () => csvFile ?? null} filenamePrefix="resource_requests" /> } @@ -241,7 +249,7 @@ export default function ListView() {
-
{showResourceCardList(data?.results || [])}
+
{showResourceCardList(resourcesList?.results || [])}
- +
)} diff --git a/src/pages/Encounters/EncounterList.tsx b/src/pages/Encounters/EncounterList.tsx index b4abc39fe7a..c9ff35fff4d 100644 --- a/src/pages/Encounters/EncounterList.tsx +++ b/src/pages/Encounters/EncounterList.tsx @@ -1,4 +1,4 @@ -import { useQuery } from "@tanstack/react-query"; +import { keepPreviousData, useQuery } from "@tanstack/react-query"; import { format } from "date-fns"; import { Link } from "raviger"; import { useCallback } from "react"; @@ -169,6 +169,8 @@ export function EncounterList({ }, }), enabled: !propEncounters && !encounter_id, + placeholderData: keepPreviousData, + staleTime: 60 * 1000, }); const { data: queryEncounter } = useQuery({ diff --git a/src/pages/Facility/FacilitiesPage.tsx b/src/pages/Facility/FacilitiesPage.tsx index 14b75a686a5..b5f219c923c 100644 --- a/src/pages/Facility/FacilitiesPage.tsx +++ b/src/pages/Facility/FacilitiesPage.tsx @@ -1,5 +1,5 @@ import careConfig from "@careConfig"; -import { useQuery } from "@tanstack/react-query"; +import { keepPreviousData, useQuery } from "@tanstack/react-query"; import { Link } from "raviger"; import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -59,6 +59,8 @@ export function FacilitiesPage() { }, }), enabled: !!qParams.organization, + placeholderData: keepPreviousData, + staleTime: 60 * 1000, }); return ( diff --git a/src/pages/Facility/FacilityDetailsPage.tsx b/src/pages/Facility/FacilityDetailsPage.tsx index c652748bd7f..f11b37e47f8 100644 --- a/src/pages/Facility/FacilityDetailsPage.tsx +++ b/src/pages/Facility/FacilityDetailsPage.tsx @@ -1,4 +1,4 @@ -import { useQuery } from "@tanstack/react-query"; +import { keepPreviousData, useQuery } from "@tanstack/react-query"; import { useTranslation } from "react-i18next"; import { toast } from "sonner"; @@ -49,6 +49,8 @@ export function FacilityDetailsPage({ id }: Props) { pathParams: { facility_id: id }, silent: true, }), + placeholderData: keepPreviousData, + staleTime: 60 * 1000, }); if (docError) { diff --git a/src/pages/Organization/OrganizationFacilities.tsx b/src/pages/Organization/OrganizationFacilities.tsx index ff55fa2fc04..90becde0a24 100644 --- a/src/pages/Organization/OrganizationFacilities.tsx +++ b/src/pages/Organization/OrganizationFacilities.tsx @@ -1,4 +1,4 @@ -import { useQuery } from "@tanstack/react-query"; +import { keepPreviousData, useQuery } from "@tanstack/react-query"; import { Link } from "raviger"; import { useTranslation } from "react-i18next"; @@ -48,6 +48,8 @@ export default function OrganizationFacilities({ }, }), enabled: !!id, + placeholderData: keepPreviousData, + staleTime: 60 * 1000, }); if (!id) { diff --git a/src/pages/Organization/OrganizationPatients.tsx b/src/pages/Organization/OrganizationPatients.tsx index 98cca56915a..7d467228d0c 100644 --- a/src/pages/Organization/OrganizationPatients.tsx +++ b/src/pages/Organization/OrganizationPatients.tsx @@ -1,4 +1,4 @@ -import { useQuery } from "@tanstack/react-query"; +import { keepPreviousData, useQuery } from "@tanstack/react-query"; import { Link } from "raviger"; import { useCallback, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -83,6 +83,8 @@ export default function OrganizationPatients({ id, navOrganizationId }: Props) { }, }), enabled: !!id && !!organization, + placeholderData: keepPreviousData, + staleTime: 60 * 1000, }); if (!id) { From 4271a427d3c1afe7f5980e1a0f850344f24a116c Mon Sep 17 00:00:00 2001 From: rajku-dev Date: Wed, 29 Jan 2025 09:55:26 +0530 Subject: [PATCH 2/8] fix translation --- public/locale/en.json | 2 +- src/components/Resource/ResourceList.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/public/locale/en.json b/public/locale/en.json index 18b6cb130db..93f91f6aca5 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -577,7 +577,7 @@ "confirm_transfer_complete": "Confirm Transfer Complete!", "confirm_unavailability": "Confirm Unavailability", "confirmed": "Confirmed", - "consent_status": "Consent Status", + "consent__status": "Consent Status", "consult": "Consult", "consultation_history": "Consultation History", "consultation_missing_warning": "You have not created a consultation for the patient in", diff --git a/src/components/Resource/ResourceList.tsx b/src/components/Resource/ResourceList.tsx index 2d78a891904..62fc03f68d8 100644 --- a/src/components/Resource/ResourceList.tsx +++ b/src/components/Resource/ResourceList.tsx @@ -267,7 +267,7 @@ export default function ListView() { {t("LOG_UPDATE_FIELD_LABEL__patient_category")}
- {t("consent_status")} + {t("consent__status")}
{t("facilities")} From e63205d3ba1a13bfaceda61cdeef0737e392b0b6 Mon Sep 17 00:00:00 2001 From: rajku-dev Date: Thu, 30 Jan 2025 03:44:00 +0530 Subject: [PATCH 3/8] modify queryKey --- src/components/Resource/ResourceList.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/Resource/ResourceList.tsx b/src/components/Resource/ResourceList.tsx index 62fc03f68d8..3331be03772 100644 --- a/src/components/Resource/ResourceList.tsx +++ b/src/components/Resource/ResourceList.tsx @@ -44,7 +44,7 @@ export default function ListView() { isLoading: loading, refetch: refetchResources, } = useQuery({ - queryKey: ["resourceRequests", qParams], + queryKey: [routes.listResourceRequests.path, qParams], queryFn: query.debounced(routes.listResourceRequests, { queryParams: formatFilter({ ...qParams, @@ -57,7 +57,10 @@ export default function ListView() { }); const { data: csvFile } = useQuery({ - queryKey: ["downloadResourcesCsv", appliedFilters], + queryKey: [ + routes.downloadResourceRequests.path, + { ...appliedFilters, csv: true }, + ], queryFn: query(routes.downloadResourceRequests, { queryParams: { ...appliedFilters, csv: true }, }), From 07d57e133f7ea41a254665bb155a9ca56c6a2c35 Mon Sep 17 00:00:00 2001 From: rajku-dev Date: Thu, 30 Jan 2025 05:40:20 +0530 Subject: [PATCH 4/8] fixes #10269 : smooth transition in comment section pagination --- src/CAREUI/misc/PaginatedList.tsx | 12 ++---------- src/Utils/request/useQuery.ts | 3 ++- src/components/Resource/ResourceCommentSection.tsx | 4 ---- 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/src/CAREUI/misc/PaginatedList.tsx b/src/CAREUI/misc/PaginatedList.tsx index 01b9b0538b5..31cded2f047 100644 --- a/src/CAREUI/misc/PaginatedList.tsx +++ b/src/CAREUI/misc/PaginatedList.tsx @@ -154,7 +154,7 @@ interface ItemsProps { const Items = (props: ItemsProps) => { const { loading, items } = useContextualized(); - if (loading || items.length === 0) { + if (items.length === 0) { return null; } @@ -182,16 +182,8 @@ interface PaginatorProps { hideIfSinglePage?: boolean; } -const Paginator = ({ - className, - hideIfSinglePage, -}: PaginatorProps) => { +const Paginator = ({ className, hideIfSinglePage }: PaginatorProps) => { const { data, perPage, currentPage, setPage } = useContextualized(); - const { loading } = useContextualized(); - - if (loading) { - return null; - } if (hideIfSinglePage && (data?.count ?? 0) <= perPage) { return null; diff --git a/src/Utils/request/useQuery.ts b/src/Utils/request/useQuery.ts index 422e5f96868..fcad4415417 100644 --- a/src/Utils/request/useQuery.ts +++ b/src/Utils/request/useQuery.ts @@ -1,4 +1,4 @@ -import { useQuery } from "@tanstack/react-query"; +import { keepPreviousData, useQuery } from "@tanstack/react-query"; import { useMemo, useRef } from "react"; import request from "@/Utils/request/request"; @@ -39,6 +39,7 @@ export default function useTanStackQueryInstead( }, enabled: options?.prefetch ?? true, refetchOnWindowFocus: false, + placeholderData: keepPreviousData, }); return { diff --git a/src/components/Resource/ResourceCommentSection.tsx b/src/components/Resource/ResourceCommentSection.tsx index 24adeba890b..7a81a55949f 100644 --- a/src/components/Resource/ResourceCommentSection.tsx +++ b/src/components/Resource/ResourceCommentSection.tsx @@ -8,7 +8,6 @@ import { Button } from "@/components/ui/button"; import { Textarea } from "@/components/ui/textarea"; import { Avatar } from "@/components/Common/Avatar"; -import CircularProgress from "@/components/Common/CircularProgress"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; @@ -65,9 +64,6 @@ const CommentSection = (props: { id: string }) => { {t("no_comments_available")} - - - > {(item) => } From a88a36b2bcb7a12164c6e8a543dc59c963d655f0 Mon Sep 17 00:00:00 2001 From: rajku-dev Date: Thu, 30 Jan 2025 07:34:42 +0530 Subject: [PATCH 5/8] show placeholder in questionnaireResponse --- .../ConsultationDetails/QuestionnaireResponsesList.tsx | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx b/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx index 11ba2b75c7b..d95d32af182 100644 --- a/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx +++ b/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx @@ -5,8 +5,6 @@ import PaginatedList from "@/CAREUI/misc/PaginatedList"; import { Card } from "@/components/ui/card"; -import { CardListSkeleton } from "@/components/Common/SkeletonLoading"; - import routes from "@/Utils/request/api"; import { formatDateTime, properCase } from "@/Utils/utils"; import { Encounter } from "@/types/emr/encounter"; @@ -148,12 +146,6 @@ export default function QuestionnaireResponsesList({ encounter }: Props) { - -
- -
-
- className="grid gap-4"> {(item) => ( Date: Thu, 30 Jan 2025 08:24:08 +0530 Subject: [PATCH 6/8] reduce stale time --- src/components/Files/FilesTab.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Files/FilesTab.tsx b/src/components/Files/FilesTab.tsx index 03981fed09f..6212a3e8822 100644 --- a/src/components/Files/FilesTab.tsx +++ b/src/components/Files/FilesTab.tsx @@ -110,7 +110,7 @@ export const FilesTab = (props: FilesTabProps) => { }), enabled: !!type, placeholderData: keepPreviousData, - staleTime: 1000 * 60 * 5, + staleTime: 1000 * 60, }); const fileManager = useFileManager({ From 89ac0763ea6cfa8e1cecd7c32312f010a1e31d62 Mon Sep 17 00:00:00 2001 From: rajku-dev Date: Thu, 30 Jan 2025 09:59:23 +0530 Subject: [PATCH 7/8] show skeleton only for first fetch --- src/pages/Organization/OrganizationFacilities.tsx | 8 ++++++-- src/pages/Organization/OrganizationPatients.tsx | 9 ++++++--- src/pages/Organization/OrganizationUsers.tsx | 12 +++++++++--- src/pages/Organization/OrganizationView.tsx | 12 +++++++++--- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/pages/Organization/OrganizationFacilities.tsx b/src/pages/Organization/OrganizationFacilities.tsx index aee01da352f..9c128a59288 100644 --- a/src/pages/Organization/OrganizationFacilities.tsx +++ b/src/pages/Organization/OrganizationFacilities.tsx @@ -36,7 +36,11 @@ export default function OrganizationFacilities({ const { qParams, Pagination, advancedFilter, resultsPerPage, updateQuery } = useFilters({ limit: 15, cacheBlacklist: ["name"] }); - const { data: facilities, isFetching } = useQuery({ + const { + data: facilities, + isFetching, + isLoading, + } = useQuery({ queryKey: ["organizationFacilities", id, qParams], queryFn: query.debounced(routes.facility.list, { queryParams: { @@ -92,7 +96,7 @@ export default function OrganizationFacilities({ className="grid gap-4 md:grid-cols-2 lg:grid-cols-3" data-cy="facility-cards" > - {isFetching ? ( + {isLoading ? ( ) : facilities?.results?.length === 0 ? ( diff --git a/src/pages/Organization/OrganizationPatients.tsx b/src/pages/Organization/OrganizationPatients.tsx index ab94ae7f714..a6dd443f2dc 100644 --- a/src/pages/Organization/OrganizationPatients.tsx +++ b/src/pages/Organization/OrganizationPatients.tsx @@ -71,7 +71,11 @@ export default function OrganizationPatients({ id, navOrganizationId }: Props) { }); }; - const { data: patients, isFetching } = useQuery({ + const { + data: patients, + isFetching, + isLoading, + } = useQuery({ queryKey: ["organizationPatients", id, qParams], queryFn: query.debounced(organizationApi.listPatients, { pathParams: { id }, @@ -120,9 +124,8 @@ export default function OrganizationPatients({ id, navOrganizationId }: Props) { onSearch={handleSearch} onFieldChange={handleFieldChange} /> -
- {isFetching ? ( + {isLoading ? ( ) : patients?.results?.length === 0 ? ( diff --git a/src/pages/Organization/OrganizationUsers.tsx b/src/pages/Organization/OrganizationUsers.tsx index 479059fa9a3..e213f78dd75 100644 --- a/src/pages/Organization/OrganizationUsers.tsx +++ b/src/pages/Organization/OrganizationUsers.tsx @@ -1,4 +1,4 @@ -import { useQuery } from "@tanstack/react-query"; +import { keepPreviousData, useQuery } from "@tanstack/react-query"; import { useTranslation } from "react-i18next"; import CareIcon from "@/CAREUI/icons/CareIcon"; @@ -37,7 +37,11 @@ export default function OrganizationUsers({ id, navOrganizationId }: Props) { const openAddUserSheet = qParams.sheet === "add"; const openLinkUserSheet = qParams.sheet === "link"; - const { data: users, isFetching: isFetchingUsers } = useQuery({ + const { + data: users, + isFetching: isFetchingUsers, + isLoading, + } = useQuery({ queryKey: ["organizationUsers", id, qParams.search, qParams.page], queryFn: query.debounced(organizationApi.listUsers, { pathParams: { id }, @@ -48,6 +52,8 @@ export default function OrganizationUsers({ id, navOrganizationId }: Props) { }, }), enabled: !!id, + placeholderData: keepPreviousData, + staleTime: 1000 * 60, }); if (!id) { @@ -101,7 +107,7 @@ export default function OrganizationUsers({ id, navOrganizationId }: Props) { data-cy="search-user" />
- {isFetchingUsers ? ( + {isLoading ? (
diff --git a/src/pages/Organization/OrganizationView.tsx b/src/pages/Organization/OrganizationView.tsx index 88cb629baf1..473ecd69631 100644 --- a/src/pages/Organization/OrganizationView.tsx +++ b/src/pages/Organization/OrganizationView.tsx @@ -1,4 +1,4 @@ -import { useQuery } from "@tanstack/react-query"; +import { keepPreviousData, useQuery } from "@tanstack/react-query"; import { Link } from "raviger"; import { useState } from "react"; import { useTranslation } from "react-i18next"; @@ -32,7 +32,11 @@ export default function OrganizationView({ id, navOrganizationId }: Props) { const [searchQuery, setSearchQuery] = useState(""); const limit = 12; // 3x4 grid - const { data: children, isFetching } = useQuery({ + const { + data: children, + isFetching, + isLoading, + } = useQuery({ queryKey: ["organization", id, "children", page, limit, searchQuery], queryFn: query.debounced(organizationApi.list, { queryParams: { @@ -42,6 +46,8 @@ export default function OrganizationView({ id, navOrganizationId }: Props) { name: searchQuery || undefined, }, }), + placeholderData: keepPreviousData, + staleTime: 1000 * 60, }); // Hack for the sidebar to work @@ -74,7 +80,7 @@ export default function OrganizationView({ id, navOrganizationId }: Props) { - {isFetching ? ( + {isLoading ? (
From a9a656e10dda609d3c6796e0b3c8e51cf3a461ec Mon Sep 17 00:00:00 2001 From: rajku-dev Date: Thu, 30 Jan 2025 10:08:39 +0530 Subject: [PATCH 8/8] restore loading in ques resp --- .../ConsultationDetails/QuestionnaireResponsesList.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx b/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx index d95d32af182..11ba2b75c7b 100644 --- a/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx +++ b/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx @@ -5,6 +5,8 @@ import PaginatedList from "@/CAREUI/misc/PaginatedList"; import { Card } from "@/components/ui/card"; +import { CardListSkeleton } from "@/components/Common/SkeletonLoading"; + import routes from "@/Utils/request/api"; import { formatDateTime, properCase } from "@/Utils/utils"; import { Encounter } from "@/types/emr/encounter"; @@ -146,6 +148,12 @@ export default function QuestionnaireResponsesList({ encounter }: Props) {
+ +
+ +
+
+ className="grid gap-4"> {(item) => (