Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migration to useQuery: Removed PaginatedList.tsx and Update Dependent Components #10350

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
52a3fae
Migrate `PaginatedList` to useQuery
rajku-dev Feb 1, 2025
881aadb
migrate questionaire response to useQuery
rajku-dev Feb 2, 2025
6c28f88
migrate EncounterHistory to useQuery | add skeleton Loaders
rajku-dev Feb 2, 2025
d54168f
reduce limit to 5 for encounter history
rajku-dev Feb 2, 2025
0a6a30b
increase skeleton loader count to default limit
rajku-dev Feb 2, 2025
bca1bf5
migrate ResourceCommentSection to useQuery | fix CommentModel | add s…
rajku-dev Feb 2, 2025
b627460
switch to route path for query key
rajku-dev Feb 2, 2025
693bbd6
migrate patientUpdates to useQuery
rajku-dev Feb 2, 2025
09fc1ec
Delete `PaginatedList.tsx`
rajku-dev Feb 2, 2025
ccef985
set limit to results per page
rajku-dev Feb 2, 2025
66c3284
set skeleton count to resultsPerPage too
rajku-dev Feb 2, 2025
52e2e2d
Merge branch 'develop' into issue/9837/paginated-list-usequery
rajku-dev Feb 2, 2025
a8bb39e
drop debouncing | update query keys
rajku-dev Feb 2, 2025
40de037
Merge branch 'issue/9837/paginated-list-usequery' of https://github.c…
rajku-dev Feb 2, 2025
5a49388
Update src/components/Facility/ConsultationDetails/QuestionnaireRespo…
rajku-dev Feb 2, 2025
ac109e1
switch to useMutaion for comment creation
rajku-dev Feb 2, 2025
e3622c9
Merge branch 'issue/9837/paginated-list-usequery' of https://github.c…
rajku-dev Feb 2, 2025
ad8e3d5
drop blacklist
rajku-dev Feb 2, 2025
6a7118e
Merge branch 'develop' into issue/9837/paginated-list-usequery
rajku-dev Feb 2, 2025
5cb5ba1
use `useQueryParams` instead of `useFilters`
rajku-dev Feb 3, 2025
c3f1fb6
Merge branch 'issue/9837/paginated-list-usequery' of https://github.c…
rajku-dev Feb 3, 2025
865aa8f
drop loading alias and fetching
rajku-dev Feb 3, 2025
e205f00
add type to useQueryParams
rajku-dev Feb 3, 2025
febc096
set page items limit to RESULT_PER_PAGE_LIMIT
rajku-dev Feb 3, 2025
379fa05
Merge branch 'develop' into issue/9837/paginated-list-usequery
rajku-dev Feb 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 47 additions & 34 deletions src/CAREUI/misc/PaginatedList.tsx
rajku-dev marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { UseQueryResult, useQuery } from "@tanstack/react-query";
import { createContext, useContext, useEffect, useState } from "react";

import CareIcon from "@/CAREUI/icons/CareIcon";
Expand All @@ -6,21 +7,22 @@

import Pagination from "@/components/Common/Pagination";

import { ApiRoute, PaginatedResponse } from "@/Utils/request/types";
import useTanStackQueryInstead, {
QueryOptions,
} from "@/Utils/request/useQuery";
import apiQuery from "@/Utils/request/query";
import {
ApiRoute,
PaginatedResponse,
QueryParams,
} from "@/Utils/request/types";
import { classNames } from "@/Utils/utils";

const DEFAULT_PER_PAGE_LIMIT = 14;

interface PaginatedListContext<TItem>
extends ReturnType<typeof useTanStackQueryInstead<PaginatedResponse<TItem>>> {
type PaginatedListContext<TItem> = UseQueryResult<PaginatedResponse<TItem>> & {
items: TItem[];
perPage: number;
currentPage: number;
setPage: (page: number) => void;
}
};

const context = createContext<PaginatedListContext<object> | null>(null);

Expand All @@ -34,41 +36,52 @@
return ctx as PaginatedListContext<TItem>;
}

interface Props<TItem> extends QueryOptions<PaginatedResponse<TItem>> {
interface Props<TItem> {
route: ApiRoute<PaginatedResponse<TItem>>;
perPage?: number;
initialPage?: number;
onPageChange?: (page: number) => void;
queryCB?: (
query: ReturnType<typeof useTanStackQueryInstead<PaginatedResponse<TItem>>>,
) => void;
queryCB?: (query: UseQueryResult<PaginatedResponse<TItem>>) => void;
pathParams?: Record<string, string>;
queryParams?: QueryParams;
silent?: boolean | ((response: Response) => boolean);
signal?: AbortSignal;
headers?: HeadersInit;
children: (
ctx: PaginatedListContext<TItem>,
query: ReturnType<typeof useTanStackQueryInstead<PaginatedResponse<TItem>>>,
query: UseQueryResult<PaginatedResponse<TItem>>,
) => JSX.Element | JSX.Element[];
}

export default function PaginatedList<TItem extends object>({
children,
route,
perPage = DEFAULT_PER_PAGE_LIMIT,
onPageChange,
initialPage,
pathParams,
queryParams,
queryCB,
...queryOptions
...apiCallOptions
}: Props<TItem>) {
const [currentPage, _setPage] = useState(queryOptions.initialPage ?? 1);
const [currentPage, _setPage] = useState(initialPage ?? 1);

const setPage = (page: number) => {
_setPage(page);
queryOptions.onPageChange?.(page);
onPageChange?.(page);
};

const query = useTanStackQueryInstead(route, {
...queryOptions,
query: {
...queryOptions.query,
limit: perPage,
offset: (currentPage - 1) * perPage,
},
const query = useQuery({
queryKey: [route.path, currentPage, perPage, queryParams],
queryFn: apiQuery(route, {
queryParams: {
limit: perPage,
offset: (currentPage - 1) * perPage,
...queryParams,
},
pathParams,
...apiCallOptions,
}),
});

const items = query.data?.results ?? [];
Expand All @@ -77,7 +90,7 @@
if (queryCB) {
queryCB(query);
}
}, [query]);

Check warning on line 93 in src/CAREUI/misc/PaginatedList.tsx

View workflow job for this annotation

GitHub Actions / cypress-run (1)

React Hook useEffect has a missing dependency: 'queryCB'. Either include it or remove the dependency array. If 'queryCB' changes too often, find the parent component that defines it and wrap that definition in useCallback

return (
<context.Provider
Expand All @@ -96,9 +109,9 @@
}

const WhenEmpty = <TItem extends object>(props: WhenEmptyProps) => {
const { items, loading } = useContextualized<TItem>();
const { items, isLoading } = useContextualized<TItem>();

if (loading || items.length > 0) {
if (isLoading || items.length > 0) {
return null;
}

Expand All @@ -108,9 +121,9 @@
PaginatedList.WhenEmpty = WhenEmpty;

const WhenLoading = <TItem extends object>(props: WhenEmptyProps) => {
const { loading } = useContextualized<TItem>();
const { isLoading } = useContextualized<TItem>();

if (!loading) {
if (!isLoading) {
return null;
}

Expand All @@ -124,18 +137,18 @@
}

const Refresh = ({ label = "Refresh", ...props }: CommonButtonProps) => {
const { loading, refetch } = useContextualized<object>();
const { isLoading, refetch } = useContextualized<object>();

return (
<Button
variant="secondary"
{...props}
onClick={() => refetch()}
disabled={loading}
disabled={isLoading}
>
<CareIcon
icon="l-sync"
className={classNames("text-lg", loading && "animate-spin")}
className={classNames("text-lg", isLoading && "animate-spin")}
/>
<span>{label}</span>
</Button>
Expand All @@ -152,15 +165,15 @@
}

const Items = <TItem extends object>(props: ItemsProps<TItem>) => {
const { loading, items } = useContextualized<TItem>();
const { isLoading, items } = useContextualized<TItem>();
rajku-dev marked this conversation as resolved.
Show resolved Hide resolved

if (loading || items.length === 0) {
if (isLoading || items.length === 0) {
return null;
}

return (
<ul className={props.className}>
{loading && props.shimmer
{isLoading && props.shimmer
? Array.from({ length: props.shimmerCount ?? 8 }).map((_, i) => (
<li key={i} className="w-full">
{props.shimmer}
Expand All @@ -187,9 +200,9 @@
hideIfSinglePage,
}: PaginatorProps) => {
const { data, perPage, currentPage, setPage } = useContextualized<object>();
const { loading } = useContextualized<TItem>();
const { isLoading } = useContextualized<TItem>();

if (loading) {
if (isLoading) {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { useQuery } from "@tanstack/react-query";
import { t } from "i18next";
import { useTranslation } from "react-i18next";

import PaginatedList from "@/CAREUI/misc/PaginatedList";

import { Badge } from "@/components/ui/badge";
import { Card } from "@/components/ui/card";
import { Separator } from "@/components/ui/separator";

import { CardListSkeleton } from "@/components/Common/SkeletonLoading";

import useFilters from "@/hooks/useFilters";

import routes from "@/Utils/request/api";
import query from "@/Utils/request/query";
import { formatDateTime, properCase } from "@/Utils/utils";
import { AllergyIntoleranceRequest } from "@/types/emr/allergyIntolerance/allergyIntolerance";
import { DiagnosisRequest } from "@/types/emr/diagnosis/diagnosis";
Expand Down Expand Up @@ -276,43 +278,57 @@ export default function QuestionnaireResponsesList({
}: Props) {
const { t } = useTranslation();

const { qParams, Pagination, resultsPerPage } = useFilters({
limit: 15,
cacheBlacklist: ["questionnaire"],
rajku-dev marked this conversation as resolved.
Show resolved Hide resolved
});

const {
data: responseData,
isFetching: isFetchingResponses,
isLoading,
} = useQuery({
queryKey: ["questionnaireResponses", patientId, qParams, encounter?.id],
queryFn: query.debounced(routes.getQuestionnaireResponses, {
rajku-dev marked this conversation as resolved.
Show resolved Hide resolved
pathParams: { patientId },
queryParams: {
encounter: encounter?.id,
limit: resultsPerPage,
offset: ((qParams.page ?? 1) - 1) * resultsPerPage,
},
}),
});

return (
<PaginatedList
route={routes.getQuestionnaireResponses}
pathParams={{
patientId: patientId,
}}
query={{
...(encounter && { encounter: encounter.id }),
}}
>
{() => (
<div className="mt-4 flex w-full flex-col gap-4">
<div className="mt-4 gap-4">
<div className="max-w-full">
{isLoading ? (
<div className="grid gap-5">
<CardListSkeleton count={3} />
</div>
) : (
<div>
<PaginatedList.WhenEmpty>
{!isFetchingResponses && responseData?.results?.length === 0 ? (
<Card className="p-6">
<div className="text-lg font-medium text-gray-500">
{t("no_questionnaire_responses")}
</div>
</Card>
</PaginatedList.WhenEmpty>

<PaginatedList.WhenLoading>
<div className="grid gap-5">
<CardListSkeleton count={3} />
</div>
</PaginatedList.WhenLoading>

<PaginatedList.Items<QuestionnaireResponse> className="grid gap-4">
{(item) => <ResponseCard key={item.id} item={item} />}
</PaginatedList.Items>

<div className="flex w-full items-center justify-center mt-4">
<PaginatedList.Paginator hideIfSinglePage />
</div>
) : (
<ul className="grid gap-4">
{responseData?.results?.map((item: QuestionnaireResponse) => (
<li key={item.id} className="w-full">
<ResponseCard key={item.id} item={item} />
</li>
))}
<div className="flex w-full items-center justify-center mt-4">
<Pagination totalCount={responseData?.count || 0} />
</div>
</ul>
)}
</div>
</div>
)}
</PaginatedList>
)}
</div>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const EncounterHistory = (props: PatientProps) => {
return (
<PaginatedList
route={routes.encounter.list}
query={{ patient: patientId }}
queryParams={{ patient: patientId }}
perPage={5}
>
{() => (
Expand Down
Loading