Skip to content

ENG-405 Add infinite pagination for prescription list in encounter#16409

Open
NikhilA8606 wants to merge 11 commits into
developfrom
ENG-405-add-infinite-pagination-for-prescription-list-in-encounter
Open

ENG-405 Add infinite pagination for prescription list in encounter#16409
NikhilA8606 wants to merge 11 commits into
developfrom
ENG-405-add-infinite-pagination-for-prescription-list-in-encounter

Conversation

@NikhilA8606

@NikhilA8606 NikhilA8606 commented Jun 2, 2026

Copy link
Copy Markdown
Member

Proposed Changes

Added infinite pagination for prescription list in encounter

Screen.Recording.2026-06-02.at.3.48.08.PM.mov

ENG-405

Tagging: @ohcnetwork/care-fe-code-reviewers

Merge Checklist

  • Add specs that demonstrate the bug or test the new feature.
  • Update product documentation.
  • Ensure that UI text is placed in I18n files.
  • Prepare a screenshot or demo video for the changelog entry and attach it to the issue.
  • Request peer reviews.
  • Complete QA on mobile devices.
  • Complete QA on desktop devices.
  • Add or update Playwright tests for related changes

Summary by CodeRabbit

  • New Features
    • Prescription lists now support infinite scrolling, automatically loading additional results as you reach the end of the current list (offset/limit pagination).
    • Works consistently across both desktop and mobile/drawer views.
  • UX Improvements
    • A bottom loading skeleton is shown while more prescriptions are being fetched.
  • Chores
    • Updated the intersection-observer dependency to the latest major version to improve scroll detection reliability.

@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

PrescriptionListSelector now uses offset/limit infinite pagination, loads more prescriptions when a sentinel enters view, flattens paged results for lookup and rendering, and passes loading state plus the sentinel ref into PrescriptionList.

Changes

Infinite Scroll Implementation

Layer / File(s) Summary
Dependency and import setup
package.json, src/components/Medicine/PrescriptionListSelector.tsx
react-intersection-observer is updated to ^10.0.3. useQuery is replaced with useInfiniteQuery, useOnInView is added, and RESULTS_PER_PAGE_LIMIT is introduced.
Infinite query and sentinel trigger
src/components/Medicine/PrescriptionListSelector.tsx
useInfiniteQuery requests prescriptions with limit and offset, computes the next page offset from lastPage.count and fetched page count, flattens data.pages into prescriptions, and uses useOnInView to call fetchNextPage() when the sentinel is visible.
Flattened data passed to list views
src/components/Medicine/PrescriptionListSelector.tsx
selectedPrescription now searches the flattened prescriptions array, and both desktop and drawer/mobile PrescriptionList paths receive prescriptions plus loadMoreRef and isFetchingNextPage.
Sentinel card and loading skeleton
src/components/Medicine/PrescriptionListSelector.tsx
PrescriptionList props include isFetchingNextPage and a sentinel ref, the render loop tracks item index to attach the ref to the last card, and a bottom CardListSkeleton renders while the next page is loading.

Suggested labels

needs testing, needs review

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: infinite pagination for the prescription list in encounters.
Description check ✅ Passed The description includes Proposed Changes, a demo link, tagging, and the merge checklist, so it is mostly complete.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ENG-405-add-infinite-pagination-for-prescription-list-in-encounter

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 2, 2026

Copy link
Copy Markdown

Deploying care-preview with  Cloudflare Pages  Cloudflare Pages

Latest commit: 1c30026
Status: ✅  Deploy successful!
Preview URL: https://a3a25e96.care-preview-a7w.pages.dev
Branch Preview URL: https://eng-405-add-infinite-paginat.care-preview-a7w.pages.dev

View logs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds infinite pagination to the encounter prescription selector so the prescriptions sidebar/drawer can load additional pages as the user scrolls, instead of fetching the full list in a single request.

Changes:

  • Replaced the single useQuery prescription fetch with useInfiniteQuery using limit/offset.
  • Added an intersection-observer trigger to call fetchNextPage() when the last item comes into view.
  • Appended a loading skeleton while fetching subsequent pages.

Comment thread src/components/Medicine/PrescriptionListSelector.tsx Outdated
Comment thread src/components/Medicine/PrescriptionListSelector.tsx Outdated
@greptile-apps

greptile-apps Bot commented Jun 2, 2026

Copy link
Copy Markdown

Greptile Summary

This PR replaces the single useQuery call in PrescriptionListSelector with useInfiniteQuery + useOnInView to support offset-based infinite scrolling, and bumps react-intersection-observer from v9 to v10 to use the new useOnInView hook.

  • facilityId is correctly included in the queryKey and RESULTS_PER_PAGE_LIMIT is hoisted to module scope — both addressing concerns raised in earlier review rounds.
  • The loadMoreRef from useOnInView is attached to the last item in items (which includes the synthetic "all prescriptions" entry), and a loading skeleton (CardListSkeleton) is shown while fetching the next page.
  • Two functional issues noted in previous review rounds — the shared loadMoreRef between the always-mounted desktop list and the drawer list, and the inability to resolve a selectedPrescription that lives on a page not yet loaded — remain present in this revision.

Confidence Score: 3/5

The core infinite-pagination logic is correct, but two unresolved functional defects from prior review rounds are still present in PrescriptionListSelector.tsx and should be addressed before merging.

The offset/count calculation in getNextPageParam is accurate, the facilityId query-key fix is in place, and the library upgrade is straightforward. However, the single loadMoreRef shared between the always-mounted desktop list and the drawer list means the intersection observer can silently detach after the drawer is closed on mobile, leaving desktop infinite scroll broken for the rest of that session. Additionally, a prescription selected from a page beyond the first batch cannot be resolved to an object from the already-loaded slice, so the mobile trigger button falls back to the select_prescription placeholder even though a valid selection exists.

src/components/Medicine/PrescriptionListSelector.tsx — the ref-sharing and selected-item-resolution issues both live here

Important Files Changed

Filename Overview
src/components/Medicine/PrescriptionListSelector.tsx Migrates from useQuery to useInfiniteQuery with offset pagination and useOnInView for scroll detection; two pre-existing functional issues flagged in earlier review rounds remain unresolved in this version
package.json Bumps react-intersection-observer from ^9.15.1 to ^10.0.3 to gain access to the useOnInView API
package-lock.json Lock file updated to reflect the react-intersection-observer v10.0.3 install; no other dependency changes

Reviews (8): Last reviewed commit: "rename prop name" | Re-trigger Greptile

Comment thread src/components/Medicine/PrescriptionListSelector.tsx Outdated
Comment thread src/components/Medicine/PrescriptionListSelector.tsx
Comment thread src/components/Medicine/PrescriptionListSelector.tsx Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/Medicine/PrescriptionListSelector.tsx`:
- Around line 66-72: The queryKey for the prescriptions infinite query is
missing facilityId, causing stale cached results when facility changes; update
the queryKey array used where queryKey: ["infinite-prescriptions", patientId,
encounterId] (in PrescriptionListSelector) to include facilityId so it becomes
["infinite-prescriptions", patientId, encounterId, facilityId], ensuring the
queryFn (which calls prescriptionApi.list with facility: facilityId) refetches
when facilityId changes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: c7813f98-2ea9-4848-8fd4-509331f5da92

📥 Commits

Reviewing files that changed from the base of the PR and between 353bca4 and 778d838.

📒 Files selected for processing (1)
  • src/components/Medicine/PrescriptionListSelector.tsx

Comment thread src/components/Medicine/PrescriptionListSelector.tsx Outdated
@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown

🎭 Playwright Test Results

Status: ✅ Passed
Test Shards: 3

Metric Count
Total Tests 328
✅ Passed 328
❌ Failed 0
⏭️ Skipped 0

📊 Detailed results are available in the playwright-final-report artifact.

Run: #9735

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/Medicine/PrescriptionListSelector.tsx (1)

122-130: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Shared intersection observer ref may cause infinite scroll to fail on one viewport.

The same ref from useInView() is passed to both the desktop and mobile PrescriptionList components. Since useInView tracks a single element, and both lists are rendered simultaneously (CSS-hidden, not conditionally rendered), the ref callback will be invoked for both sentinels. The last assignment wins, so the intersection observer may watch the hidden list's sentinel instead of the visible one.

Proposed fix: Use separate refs for each viewport
  const { ref, inView } = useInView();
+ const { ref: desktopRef, inView: desktopInView } = useInView();
+ const { ref: mobileRef, inView: mobileInView } = useInView();

  // ...

  useEffect(() => {
-   if (inView && hasNextPage) {
+   if ((desktopInView || mobileInView) && hasNextPage) {
      fetchNextPage();
    }
- }, [inView, hasNextPage, fetchNextPage]);
+ }, [desktopInView, mobileInView, hasNextPage, fetchNextPage]);

  // Desktop list
  <PrescriptionList
    prescriptions={prescriptions}
    selectedPrescriptionId={selectedPrescriptionId}
    onSelectPrescription={onSelectPrescription}
-   ref={ref}
+   ref={desktopRef}
    isFetchingNextPage={isFetchingNextPage}
  />

  // Mobile list inside Drawer
  <PrescriptionList
-   ref={ref}
+   ref={mobileRef}
    isFetchingNextPage={isFetchingNextPage}
    prescriptions={prescriptions}
    selectedPrescriptionId={selectedPrescriptionId}
    onSelectPrescription={handleSelectPrescription}
  />

Also applies to: 188-194

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/Medicine/PrescriptionListSelector.tsx` around lines 122 - 130,
The shared intersection-observer ref passed as ref={ref} to both
PrescriptionList instances causes the observer to attach to whichever sentinel
was assigned last; fix by creating separate refs/observers for desktop and
mobile (e.g., useInView twice: const { ref: desktopRef } = useInView(...) and
const { ref: mobileRef } = useInView(...)) and pass desktopRef to the desktop
PrescriptionList and mobileRef to the mobile PrescriptionList (update any
associated inView handlers/logic accordingly); apply the same change to the
other occurrence around lines 188-194 so each viewport has its own
observer/sentinel.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/components/Medicine/PrescriptionListSelector.tsx`:
- Around line 122-130: The shared intersection-observer ref passed as ref={ref}
to both PrescriptionList instances causes the observer to attach to whichever
sentinel was assigned last; fix by creating separate refs/observers for desktop
and mobile (e.g., useInView twice: const { ref: desktopRef } = useInView(...)
and const { ref: mobileRef } = useInView(...)) and pass desktopRef to the
desktop PrescriptionList and mobileRef to the mobile PrescriptionList (update
any associated inView handlers/logic accordingly); apply the same change to the
other occurrence around lines 188-194 so each viewport has its own
observer/sentinel.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: c6235204-f567-4813-9a76-b72fc61fcf0f

📥 Commits

Reviewing files that changed from the base of the PR and between 778d838 and 096af97.

📒 Files selected for processing (1)
  • src/components/Medicine/PrescriptionListSelector.tsx

Comment thread src/components/Medicine/PrescriptionListSelector.tsx Outdated
Comment thread src/components/Medicine/PrescriptionListSelector.tsx Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 3 changed files in this pull request and generated 3 comments.

Comment thread src/components/Medicine/PrescriptionListSelector.tsx
Comment thread src/components/Medicine/PrescriptionListSelector.tsx
Comment thread src/components/Medicine/PrescriptionListSelector.tsx
Copilot AI review requested due to automatic review settings June 18, 2026 10:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 3 changed files in this pull request and generated 3 comments.

Comment thread src/components/Medicine/PrescriptionListSelector.tsx
Comment thread src/components/Medicine/PrescriptionListSelector.tsx
Comment thread src/components/Medicine/PrescriptionListSelector.tsx
@NikhilA8606

Copy link
Copy Markdown
Member Author

Try with useInView and compare 👍

We don't need to manage the inView state just to call fetchNextPage(), so useOnInView lets us react directly to visibility changes without introducing unnecessary state updates and re-renders that's why i used useOnInview here

@github-actions github-actions Bot added needs-triage question Further information is requested labels Jun 18, 2026
@NikhilA8606 NikhilA8606 requested a review from Jacobjeevan June 18, 2026 11:22
@NikhilA8606 NikhilA8606 removed question Further information is requested needs-triage labels Jun 18, 2026
@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{}

Copilot AI review requested due to automatic review settings June 24, 2026 08:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 3 changed files in this pull request and generated 2 comments.

Comment thread src/components/Medicine/PrescriptionListSelector.tsx
Comment thread src/components/Medicine/PrescriptionListSelector.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/Medicine/PrescriptionListSelector.tsx (1)

113-115: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Do not resolve the selected prescription only from loaded pages.

With infinite pagination, a valid selectedPrescriptionId can refer to a prescription beyond the loaded pages, causing the mobile trigger to fall through to select_prescription. Ensure the selected prescription is fetched/passed independently, or include it in the initial loaded data.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/Medicine/PrescriptionListSelector.tsx` around lines 113 - 115,
The current selectedPrescription lookup in PrescriptionListSelector only
searches the loaded prescriptions array, so a valid selectedPrescriptionId from
an unloaded page can be missed. Update the selection flow around
selectedPrescriptionId/prescriptions so the chosen prescription is obtained
independently of infinite pagination, either by fetching/passing that
prescription separately or by ensuring it is included in the initial loaded
data. Keep the mobile trigger logic using the resolved prescription from
PrescriptionListSelector rather than falling back to select_prescription when
the item exists but is not yet in loaded pages.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/Medicine/PrescriptionListSelector.tsx`:
- Around line 90-91: The `useOnInView` callback in `PrescriptionListSelector` is
leaving a sentinel debug log on the prescription list scrolling path. Remove the
`console.log` from the `loadMoreRef`/`useOnInView` handler and keep the callback
focused on the load-more behavior only, so repeated in-view events no longer
emit noisy production logs.

---

Outside diff comments:
In `@src/components/Medicine/PrescriptionListSelector.tsx`:
- Around line 113-115: The current selectedPrescription lookup in
PrescriptionListSelector only searches the loaded prescriptions array, so a
valid selectedPrescriptionId from an unloaded page can be missed. Update the
selection flow around selectedPrescriptionId/prescriptions so the chosen
prescription is obtained independently of infinite pagination, either by
fetching/passing that prescription separately or by ensuring it is included in
the initial loaded data. Keep the mobile trigger logic using the resolved
prescription from PrescriptionListSelector rather than falling back to
select_prescription when the item exists but is not yet in loaded pages.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2bbe875f-e013-49bd-9462-e0600e3288a6

📥 Commits

Reviewing files that changed from the base of the PR and between e72283d and 3cbeaaf.

📒 Files selected for processing (1)
  • src/components/Medicine/PrescriptionListSelector.tsx

Comment thread src/components/Medicine/PrescriptionListSelector.tsx Outdated
Copilot AI review requested due to automatic review settings June 24, 2026 09:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.

Comment thread src/components/Medicine/PrescriptionListSelector.tsx
Comment thread src/components/Medicine/PrescriptionListSelector.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/components/Medicine/PrescriptionListSelector.tsx (2)

111-113: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Preserve selected prescriptions that are not in the loaded page window.

After switching to infinite pagination, selectedPrescription only searches already fetched pages. If selectedPrescriptionId is initialized from route/state for an older prescription beyond the first page, the selector renders select_prescription and no item appears selected until that page is fetched.

Fetch the selected prescription separately or ensure the page containing selectedPrescriptionId is loaded before deriving this value.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/Medicine/PrescriptionListSelector.tsx` around lines 111 - 113,
The selected prescription lookup in PrescriptionListSelector only searches the
currently loaded prescriptions array, so a route/state-selected prescription
from an older page can disappear until that page is fetched. Update the
selectedPrescription derivation to either load the prescription matching
selectedPrescriptionId separately or ensure the page containing that id is
fetched before computing the selected value, so the selector can preserve and
render selections outside the current page window.

89-93: 🎯 Functional Correctness | 🟠 Major

Split the load-more ref between the desktop and drawer lists. useOnInView tracks a single observed node, so reusing one ref for both PrescriptionList instances lets the last mounted sentinel take over and can break infinite scroll in the other view. Use separate refs for each list and keep the same load-more handler.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/Medicine/PrescriptionListSelector.tsx` around lines 89 - 93,
The load-more sentinel is currently shared by both `PrescriptionList` instances,
so `useOnInView` only tracks the last mounted node and can break infinite scroll
in one view. Update `PrescriptionListSelector` to create separate in-view refs
for the desktop and drawer lists while keeping the same `fetchNextPage` handler
logic, and attach each ref to its own `PrescriptionList` load-more element.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/components/Medicine/PrescriptionListSelector.tsx`:
- Around line 111-113: The selected prescription lookup in
PrescriptionListSelector only searches the currently loaded prescriptions array,
so a route/state-selected prescription from an older page can disappear until
that page is fetched. Update the selectedPrescription derivation to either load
the prescription matching selectedPrescriptionId separately or ensure the page
containing that id is fetched before computing the selected value, so the
selector can preserve and render selections outside the current page window.
- Around line 89-93: The load-more sentinel is currently shared by both
`PrescriptionList` instances, so `useOnInView` only tracks the last mounted node
and can break infinite scroll in one view. Update `PrescriptionListSelector` to
create separate in-view refs for the desktop and drawer lists while keeping the
same `fetchNextPage` handler logic, and attach each ref to its own
`PrescriptionList` load-more element.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f92b0669-c478-4c99-b147-19d8f3438974

📥 Commits

Reviewing files that changed from the base of the PR and between d0a9ec3 and 1c30026.

📒 Files selected for processing (1)
  • src/components/Medicine/PrescriptionListSelector.tsx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants