Skip to content

feat: Add pagination in merchants page#1965

Merged
jjmata merged 3 commits into
we-promise:mainfrom
alessiocappa:FT-AddPaginationInMerchantsPage
May 26, 2026
Merged

feat: Add pagination in merchants page#1965
jjmata merged 3 commits into
we-promise:mainfrom
alessiocappa:FT-AddPaginationInMerchantsPage

Conversation

@alessiocappa
Copy link
Copy Markdown
Collaborator

@alessiocappa alessiocappa commented May 24, 2026

This PR introduces a pagination feature in the “Merchants” settings page, applicable to both family and provider merchants.

Before After
Screenshot 2026-05-24 alle 21 07 06 Screenshot 2026-05-24 alle 21 07 24

Summary by CodeRabbit

  • New Features

    • Added pagination controls to family and provider merchant lists for easier navigation.
    • Merchant list headers now show total counts (overall family and provider merchants) while paginated tables show page results.
  • Bug Fixes

    • Improved counts and visibility logic so table sections and enhanceable/unlinked tallies reflect the full merchant sets accurately.

Review Change Stack

@superagent-security superagent-security Bot added the contributor:verified Contributor passed trust analysis. label May 24, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 24, 2026

📝 Walkthrough

Walkthrough

This PR separates total merchant counts (unpaginated scopes) from paginated table results: the controller builds @all_family_merchants and @all_provider_merchants, computes linked/unlinked/enhanceable metrics from them, paginates into @family_merchants/@provider_merchants, and the view displays total counts with paginated tables and pagination controls.

Changes

Family and Provider Merchant Pagination

Layer / File(s) Summary
Controller pagination setup and merchant scoping
app/controllers/family_merchants_controller.rb
Index action now derives unpaginated @all_family_merchants and @all_provider_merchants, computes @unlinked_merchants and @enhanceable_count from those scopes, and applies pagy pagination producing @family_merchants and @provider_merchants.
View pagination controls and total counts display
app/views/family_merchants/index.html.erb
Section headers show total counts from @all_*_merchants.count; table rendering guards use @all_*_merchants.any?; pagination controls rendered beneath each table with corresponding @pagy_* objects.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • we-promise/sure#281: Modifies FamilyMerchantsController#index to change merchant collection sourcing used on the family merchants page.
  • we-promise/sure#418: Adds provider merchants alongside family merchants; related view/controller areas overlap with this pagination work.
  • we-promise/sure#262: Changes how merchant collections are sourced and counted/paginated in the same controller action.

Suggested labels

codex

Suggested reviewers

  • sokie
  • jjmata

Poem

🐰 I hopped through lists both big and small,
Counted totals first, then paged them all.
Controllers set the full and sliced view,
Views show both counts and pages too—
A tidy hop, a joyful crawl.

🚥 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: pagination is being added to the merchants page for both family and provider merchants.
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 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 and usage tips.

@superagent-security superagent-security Bot added the pr:verified PR passed security analysis. label May 24, 2026
@alessiocappa alessiocappa self-assigned this May 24, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d72de03545

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread app/controllers/family_merchants_controller.rb Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
app/views/family_merchants/index.html.erb (2)

114-116: 💤 Low value

Consider conditionally rendering pagination controls.

The pagination controls render even when there's only one page of results. While functional, this may clutter the UI when pagination isn't needed.

🎨 Proposed refinement to hide pagination when not needed
-    <div class="pt-4">
-      <%= render "shared/pagination", pagy: `@pagy_provider_merchants` %>
-    </div>
+    <% if `@pagy_provider_merchants.pages` > 1 %>
+      <div class="pt-4">
+        <%= render "shared/pagination", pagy: `@pagy_provider_merchants` %>
+      </div>
+    <% end %>
🤖 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 `@app/views/family_merchants/index.html.erb` around lines 114 - 116, Wrap the
pagination partial render in a conditional that only shows it when there is more
than one page; specifically, change the block that calls render
"shared/pagination", pagy: `@pagy_provider_merchants` inside an if
`@pagy_provider_merchants.pages` > 1 (or equivalent check) so the
"shared/pagination" partial is only rendered when `@pagy_provider_merchants.pages`
> 1.

56-58: 💤 Low value

Consider conditionally rendering pagination controls.

The pagination controls render even when there's only one page of results. While functional, this may clutter the UI when pagination isn't needed.

🎨 Proposed refinement to hide pagination when not needed
-    <div class="pt-4">
-      <%= render "shared/pagination", pagy: `@pagy_family_merchants` %>
-    </div>
+    <% if `@pagy_family_merchants.pages` > 1 %>
+      <div class="pt-4">
+        <%= render "shared/pagination", pagy: `@pagy_family_merchants` %>
+      </div>
+    <% end %>
🤖 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 `@app/views/family_merchants/index.html.erb` around lines 56 - 58, Wrap the
existing pagination render so it only shows when there are multiple pages: check
the Pagy object `@pagy_family_merchants` (for example using
`@pagy_family_merchants.pages` > 1) and only call render "shared/pagination",
pagy: `@pagy_family_merchants` when that condition is true; this will keep the UI
clean by hiding pagination controls for single-page results.
🤖 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.

Nitpick comments:
In `@app/views/family_merchants/index.html.erb`:
- Around line 114-116: Wrap the pagination partial render in a conditional that
only shows it when there is more than one page; specifically, change the block
that calls render "shared/pagination", pagy: `@pagy_provider_merchants` inside an
if `@pagy_provider_merchants.pages` > 1 (or equivalent check) so the
"shared/pagination" partial is only rendered when `@pagy_provider_merchants.pages`
> 1.
- Around line 56-58: Wrap the existing pagination render so it only shows when
there are multiple pages: check the Pagy object `@pagy_family_merchants` (for
example using `@pagy_family_merchants.pages` > 1) and only call render
"shared/pagination", pagy: `@pagy_family_merchants` when that condition is true;
this will keep the UI clean by hiding pagination controls for single-page
results.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d78346a6-fc9d-4189-9cd7-3be804c3289e

📥 Commits

Reviewing files that changed from the base of the PR and between 89f4249 and d72de03.

📒 Files selected for processing (2)
  • app/controllers/family_merchants_controller.rb
  • app/views/family_merchants/index.html.erb

Copy link
Copy Markdown
Collaborator

jjmata commented May 25, 2026

Pagination on a potentially long list is a good addition. A couple of things:

Redundant visibility condition

<% if @pagy_family_merchants.count > 0 || @family_merchants.any? %>

@pagy_family_merchants is the Pagy metadata object (not the records), and @family_merchants is the page-scoped collection. Both of these being non-empty implies the other is too, so the || check is effectively checking the same condition twice. The clearest expression of intent is:

<% if @all_family_merchants.any? %>

Same applies to the provider section.

Pagination shown even when there's only one page

The render "shared/pagination" partial is always rendered (even when there's only one page of results), which may add empty space or a blank element. This might already be handled inside the shared partial — just worth confirming it renders nothing when pagy.pages == 1.

No tests for the pagination behavior

The PR adds no controller tests asserting that the paginated variables are assigned correctly, that page 2 works, or that the total count is preserved. Given the project's convention of writing tests for critical paths, a basic test that @all_family_merchants.count is the unpaginated total and @family_merchants.count <= safe_per_page would be worthwhile.


Generated by Claude Code

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
app/views/family_merchants/index.html.erb (2)

114-116: ⚡ Quick win

Consider conditionally rendering pagination controls.

Same concern as the family merchants pagination above: the pagination block renders even when there's only one page of provider merchants. Wrap it in a conditional:

<% if `@pagy_provider_merchants.pages` > 1 %>
  <div class="pt-4">
    <%= render "shared/pagination", pagy: `@pagy_provider_merchants` %>
  </div>
<% end %>
🤖 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 `@app/views/family_merchants/index.html.erb` around lines 114 - 116, The
pagination partial is rendered even when there's only one page; wrap the block
that renders "shared/pagination" with a conditional check on the Pagy object
(use `@pagy_provider_merchants.pages` > 1) so that the div and render call only
execute when more than one page exists, keeping the reference to
`@pagy_provider_merchants` and the render "shared/pagination" invocation.

56-58: ⚡ Quick win

Consider conditionally rendering pagination controls.

The pagination block renders even when there's only one page of results. Since the shared/pagination partial doesn't guard itself (see context snippet 2), you may want to wrap this in a conditional to avoid showing unnecessary controls:

<% if `@pagy_family_merchants.pages` > 1 %>
  <div class="pt-4">
    <%= render "shared/pagination", pagy: `@pagy_family_merchants` %>
  </div>
<% end %>

This prevents extra DOM elements and visual clutter when all family merchants fit on a single page.

🤖 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 `@app/views/family_merchants/index.html.erb` around lines 56 - 58, Wrap the
pagination render in a conditional that checks the Pagy object so controls are
only shown when there is more than one page: guard the render of
"shared/pagination" using `@pagy_family_merchants.pages` > 1 (or the equivalent
Pagy helper) so the <div class="pt-4"> and the render call for the partial only
appear when `@pagy_family_merchants` has multiple 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.

Nitpick comments:
In `@app/views/family_merchants/index.html.erb`:
- Around line 114-116: The pagination partial is rendered even when there's only
one page; wrap the block that renders "shared/pagination" with a conditional
check on the Pagy object (use `@pagy_provider_merchants.pages` > 1) so that the
div and render call only execute when more than one page exists, keeping the
reference to `@pagy_provider_merchants` and the render "shared/pagination"
invocation.
- Around line 56-58: Wrap the pagination render in a conditional that checks the
Pagy object so controls are only shown when there is more than one page: guard
the render of "shared/pagination" using `@pagy_family_merchants.pages` > 1 (or the
equivalent Pagy helper) so the <div class="pt-4"> and the render call for the
partial only appear when `@pagy_family_merchants` has multiple pages.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ee920a10-9990-4d87-939d-5f9dadea484e

📥 Commits

Reviewing files that changed from the base of the PR and between c102e68 and 2a8173a.

📒 Files selected for processing (1)
  • app/views/family_merchants/index.html.erb

@jjmata jjmata merged commit bc3e5a8 into we-promise:main May 26, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor:verified Contributor passed trust analysis. pr:verified PR passed security analysis.

Development

Successfully merging this pull request may close these issues.

2 participants