Skip to content

fix(web): clamp total pages count to minimum of 1 - #544

Open
SMOGZ6783 wants to merge 1 commit into
Fundable-Protocol:mainfrom
SMOGZ6783:fix/web-use-pagination-clamp-total-pages
Open

fix(web): clamp total pages count to minimum of 1#544
SMOGZ6783 wants to merge 1 commit into
Fundable-Protocol:mainfrom
SMOGZ6783:fix/web-use-pagination-clamp-total-pages

Conversation

@SMOGZ6783

@SMOGZ6783 SMOGZ6783 commented Jul 29, 2026

Copy link
Copy Markdown

Summary

Fixes issue #422 where tables rendered 'Page 1 of 0' when data streams or transaction history were empty.

Changes Made

  • Pagination Hook (\�pps/web/src/hooks/use-pagination.ts):
    • Clamped \pageCount\ calculation to a minimum of \1\ (\Math.max(1, Math.ceil(total / pageSize))).
  • Tables (\HistoryTable.tsx, \StreamsTable.tsx):
    • Ensured total page fallback is clamped to minimum 1.
  • Hooks (\use-balance-validation.ts, \use-token-balance.ts):
    • Fixed explicit initial null value for \useRef\ and added missing client directives.

Fixes #422

Summary by CodeRabbit

  • Bug Fixes

    • Improved pagination handling for invalid, fractional, and boundary values, ensuring page navigation remains stable.
    • History and payment stream tables now correctly handle empty or limited result sets.
    • Token balance views now gracefully show no balances when an account is missing, while preserving other error reporting.
  • Reliability

    • Improved balance validation and pagination behavior across client-side interactions.
    • Added broader coverage for pagination edge cases and default scenarios.

)

Clamps pageCount to a minimum of 1 in use-pagination hook, StreamsTable, and HistoryTable so empty streams/histories render 'Page 1 of 1' instead of 'Page 1 of 0'.

Fixes Fundable-Protocol#422
@drips-wave

drips-wave Bot commented Jul 29, 2026

Copy link
Copy Markdown

@SMOGZ6783 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Pagination now clamps page counts and sanitizes range inputs, while token balance fetching handles missing accounts and related hooks receive client-module and timeout-ref updates.

Changes

Pagination normalization

Layer / File(s) Summary
Normalize pagination inputs and ranges
apps/web/src/hooks/use-pagination.ts, apps/web/src/hooks/use-pagination.test.ts
Pagination counts, page numbers, and sibling counts are normalized; boundary handling and default hook parameters are covered by tests.
Apply clamped counts to tables
apps/web/src/components/modules/history/HistoryTable.tsx, apps/web/src/components/modules/payment-stream/StreamsTable.tsx
Both tables pass clamped computed page counts to their pagination configuration.

Token balance hook handling

Layer / File(s) Summary
Handle token balance fetching and lookup
apps/web/src/hooks/use-token-balance.ts
Missing accounts return empty balances, other errors are rethrown, abort signals are typed, and asset matching uses an explicitly typed predicate.

Balance validation client lifecycle

Layer / File(s) Summary
Initialize validation timeout state
apps/web/src/hooks/use-balance-validation.ts
The hook is marked client-side and its timeout reference is initialized as nullable.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related issues

  • Fundable-Protocol/stellar_client_os#322 — Addresses the same empty-dataset pagination behavior by enforcing a minimum page count.

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The balance-hook client/ref cleanup changes are unrelated to the linked pagination bug and go beyond the issue scope. Move the balance-hook cleanup into a separate PR, or document it as required by the linked pagination fix if it truly is necessary.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly states the main fix: clamping page counts to a minimum of 1.
Linked Issues check ✅ Passed The pagination hook clamps total page count to at least 1 and adds coverage for the empty-page case.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@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: 3

🤖 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 `@apps/web/src/components/modules/payment-stream/StreamsTable.tsx`:
- Line 52: Update the pagination rendering in StreamsTable so the page indicator
renders for empty streams when pageCount is 1, showing “Page 1 of 1”. Move the
indicator outside the totalCount guard or relax that guard, while keeping
optional pagination controls hidden when totalCount is zero.

In `@apps/web/src/hooks/use-pagination.ts`:
- Around line 14-19: Update clampPageCount to treat every non-finite pageCount,
including positive Infinity, as invalid and return the minimum page count of 1;
preserve the existing ceiling behavior for finite positive values.
- Line 27: Update the safeSiblingCount normalization in the pagination hook to
replace non-finite siblingCount values with a finite fallback before applying
Math.floor, preserving the existing default for nullish values and ensuring
windowSize, left, and right receive valid numeric inputs.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b5317df1-d280-4685-9877-cb6cb4cee2b9

📥 Commits

Reviewing files that changed from the base of the PR and between 375c936 and 1960e3c.

📒 Files selected for processing (6)
  • apps/web/src/components/modules/history/HistoryTable.tsx
  • apps/web/src/components/modules/payment-stream/StreamsTable.tsx
  • apps/web/src/hooks/use-balance-validation.ts
  • apps/web/src/hooks/use-pagination.test.ts
  • apps/web/src/hooks/use-pagination.ts
  • apps/web/src/hooks/use-token-balance.ts

const router = useRouter();
const searchParams = useSearchParams();
const pageCount = Math.ceil(totalCount / limit);
const pageCount = clampPageCount(Math.ceil(totalCount / limit));

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Render the empty-stream pagination state.

Although pageCount is clamped to 1, the pagination block at Line 201 is still skipped when totalCount === 0. Empty streams therefore show no “Page 1 of 1” indicator. Render the page indicator outside that guard, or relax the guard while keeping optional controls hidden.

🤖 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 `@apps/web/src/components/modules/payment-stream/StreamsTable.tsx` at line 52,
Update the pagination rendering in StreamsTable so the page indicator renders
for empty streams when pageCount is 1, showing “Page 1 of 1”. Move the indicator
outside the totalCount guard or relax that guard, while keeping optional
pagination controls hidden when totalCount is zero.

Comment on lines +14 to +19
export const clampPageCount = (pageCount: number): number => {
if (!pageCount || Number.isNaN(pageCount) || pageCount < 1) {
return 1;
}
return Math.ceil(pageCount);
};

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Reject positive Infinity in clampPageCount.

clampPageCount(Infinity) currently returns Infinity, allowing invalid table calculations such as Math.ceil(totalCount / 0) to produce an unusable page count and an Infinity page item. Treat all non-finite values as the minimum page count.

Proposed fix
 export const clampPageCount = (pageCount: number): number => {
-  if (!pageCount || Number.isNaN(pageCount) || pageCount < 1) {
+  if (!Number.isFinite(pageCount) || pageCount < 1) {
     return 1;
   }
   return Math.ceil(pageCount);
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const clampPageCount = (pageCount: number): number => {
if (!pageCount || Number.isNaN(pageCount) || pageCount < 1) {
return 1;
}
return Math.ceil(pageCount);
};
export const clampPageCount = (pageCount: number): number => {
if (!Number.isFinite(pageCount) || pageCount < 1) {
return 1;
}
return Math.ceil(pageCount);
};
🤖 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 `@apps/web/src/hooks/use-pagination.ts` around lines 14 - 19, Update
clampPageCount to treat every non-finite pageCount, including positive Infinity,
as invalid and return the minimum page count of 1; preserve the existing ceiling
behavior for finite positive values.

const safeCurrentPage = Math.min(Math.max(1, currentPage), safePageCount);
const windowSize = siblingCount * 2 + 1;
const safePageCount = clampPageCount(pageCount);
const safeSiblingCount = Math.max(0, Math.floor(siblingCount ?? 2));

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Normalize invalid sibling counts before arithmetic.

When siblingCount is NaN, safeSiblingCount, windowSize, left, and right all become NaN; the returned range then collapses to only the first and last pages. Use a finite fallback before flooring.

Proposed fix
-  const safeSiblingCount = Math.max(0, Math.floor(siblingCount ?? 2));
+  const normalizedSiblingCount = siblingCount ?? 2;
+  const safeSiblingCount = Number.isFinite(normalizedSiblingCount)
+    ? Math.max(0, Math.floor(normalizedSiblingCount))
+    : 2;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const safeSiblingCount = Math.max(0, Math.floor(siblingCount ?? 2));
const normalizedSiblingCount = siblingCount ?? 2;
const safeSiblingCount = Number.isFinite(normalizedSiblingCount)
? Math.max(0, Math.floor(normalizedSiblingCount))
: 2;
🤖 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 `@apps/web/src/hooks/use-pagination.ts` at line 27, Update the safeSiblingCount
normalization in the pagination hook to replace non-finite siblingCount values
with a finite fallback before applying Math.floor, preserving the existing
default for nullish values and ensuring windowSize, left, and right receive
valid numeric inputs.

@Idrhas

Idrhas commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

dont forget to offramp using https://stellar.fundable.finance/offramp its fast, free and p2p rates

2 similar comments
@Idrhas

Idrhas commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

dont forget to offramp using https://stellar.fundable.finance/offramp its fast, free and p2p rates

@Idrhas

Idrhas commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

dont forget to offramp using https://stellar.fundable.finance/offramp its fast, free and p2p rates

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

web(use-pagination): clamp total pages count to minimum of 1

2 participants