From 960da6635ae3de635668c7d7a0c04fa9acba2760 Mon Sep 17 00:00:00 2001 From: Vineet Sharma Date: Mon, 29 Apr 2024 09:23:46 +0300 Subject: [PATCH] (feat) Fetch all concept references of the the form with SWR Infinite (#241) * Fetching all concepts references with useSWRInfinite * Fixed failing tests --- src/hooks/useConcepts.tsx | 50 +++++++++++++++++++++++++++++++++------ src/utils/form-helper.ts | 2 +- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/hooks/useConcepts.tsx b/src/hooks/useConcepts.tsx index 286934903..46170e690 100644 --- a/src/hooks/useConcepts.tsx +++ b/src/hooks/useConcepts.tsx @@ -1,14 +1,50 @@ -import useSWRImmutable from 'swr/immutable'; -import { openmrsFetch, OpenmrsResource, restBaseUrl } from '@openmrs/esm-framework'; +import useSWRInfinite from 'swr/infinite'; +import { FetchResponse, openmrsFetch, OpenmrsResource, restBaseUrl } from '@openmrs/esm-framework'; +import { useMemo } from 'react'; const conceptRepresentation = 'custom:(uuid,display,conceptClass:(uuid,display),answers:(uuid,display),conceptMappings:(conceptReferenceTerm:(conceptSource:(name),code)))'; -export function useConcepts(references: Set) { - // TODO: handle paging (ie when number of concepts greater than default limit per page) - const { data, error, isLoading } = useSWRImmutable<{ data: { results: Array } }, Error>( - `${restBaseUrl}/concept?references=${Array.from(references).join(',')}&v=${conceptRepresentation}`, +const chunkSize = 100; + +export function useConcepts(references: Set): { + concepts: Array | undefined; + isLoading: boolean; + error: Error | undefined; +} { + const totalCount = references.size; + const totalPages = Math.ceil(totalCount / chunkSize); + + const getUrl = (index) => { + if (index >= totalPages) { + return null; + } + + const start = index * chunkSize; + const end = start + chunkSize; + const chunk = Array.from(references).slice(start, end); + return `${restBaseUrl}/concept?references=${chunk.join(',')}&v=${conceptRepresentation}&limit=${chunkSize}`; + }; + + const { data, error, isLoading } = useSWRInfinite }>, Error>( + getUrl, openmrsFetch, + { + initialSize: totalPages, + revalidateIfStale: false, + revalidateOnFocus: false, + revalidateOnReconnect: false, + }, ); - return { concepts: data?.data.results, error, isLoading }; + + const results = useMemo( + () => ({ + concepts: data ? [].concat(data?.map((res) => res?.data?.results).flat()) : undefined, + error, + isLoading, + }), + [data, error, isLoading], + ); + + return results; } diff --git a/src/utils/form-helper.ts b/src/utils/form-helper.ts index 9da5c58ad..a5421bb7d 100644 --- a/src/utils/form-helper.ts +++ b/src/utils/form-helper.ts @@ -140,7 +140,7 @@ export function findConceptByReference(reference: string, concepts) { } else { // handle uuid return concepts?.find((concept) => { - return concept.uuid === reference; + return concept?.uuid === reference; }); } }