Skip to content

Add configurable page size selector for admin listings - #19824

Open
MikeAlhayek wants to merge 4 commits into
mainfrom
ma/page-size-selector-19816
Open

Add configurable page size selector for admin listings#19824
MikeAlhayek wants to merge 4 commits into
mainfrom
ma/page-size-selector-19816

Conversation

@MikeAlhayek

Copy link
Copy Markdown
Member

Fixes #19816

What

Adds an opt-in page size selector to admin listing pages. An administrator enables it in the general site settings and provides the list of allowed values (for example 10, 25, 50, 100). A selector then appears next to the pager on listing pages, and controllers honor the selected size when it is valid.

How it works

  • Site settings (General → Page size selection):
    • Allow users to change the page size on listing pages checkbox.
    • Page size options — a comma-separated list of allowed sizes. Validation requires at least one valid size when selection is enabled; invalid/empty entries are dropped, values are de-duplicated and sorted.
  • Server-side honoring: the selected size arrives as a pageSize query string parameter. PagerOptions.GetPageSize(int? selectedPageSize) returns the requested value only when selection is enabled and the value is one of the configured options (clamped to MaxPageSize); otherwise it falls back to the configured default. So arbitrary/unbounded page sizes are never honored.
  • Selector UI: rendered by the TheAdmin Pager view. Each option is a link to the current URL with pageSize set and the page number reset, preserving all other query string parameters (filters, search, etc.). The selected size is carried across pages by the existing pager links — no localStorage needed.

Key changes

  • PagerOptions: new AllowPageSizeSelection, PageSizeOptions, and GetPageSize(int?) validation helper.
  • Pager: new Pager(PagerParameters, PagerOptions) constructor that resolves the effective page size centrally.
  • Admin listing controllers updated to pass PagerOptions (was PagerOptions.GetPageSize()), so validation is applied uniformly. Existing overloads are unchanged and still work.
  • ISite/SiteSettings, the settings driver + view, the Settings recipe step, and the site settings deployment source persist the two new values.
  • Unit tests for PagerOptions.GetPageSize and the new Pager constructor.
  • Release note added to 4.0.0.md.

Notes / scope

  • Scoped to the admin theme (TheAdmin), where the affected listing controllers render. Front-end pagers (PagerSlim, ListPart) keep their own page-size behavior and are out of scope.
  • The feature is fully opt-in and defaults to off, so existing behavior is unchanged unless an admin enables it.
  • The issue also mentions per-route localStorage persistence; this PR uses query-string persistence instead (simpler, shareable URLs, no client state). That can be layered on later if desired.

Testing

  • dotnet build of the CMS app succeeds (0 warnings/errors).
  • New PagerOptionsTests (11 cases) pass; existing admin controller tests referencing PagerOptions still pass.

🤖 Generated with Claude Code

MikeAlhayek and others added 4 commits September 3, 2026 11:08
Add an opt-in "Page size selection" option to the general site settings.
When enabled with a list of allowed page sizes (e.g. 10, 25, 50, 100), admin
listing pages render an "Items per page" selector next to the pager.

The selected value is passed to controllers via a `pageSize` query string
parameter and honored only when selection is enabled and the value is one of
the configured options; any other value falls back to the configured default.

- PagerOptions: add AllowPageSizeSelection, PageSizeOptions, and
  GetPageSize(int?) that validates the requested size.
- Pager: add a constructor taking PagerParameters + PagerOptions that resolves
  the effective page size centrally.
- Update admin listing controllers to use the new constructor.
- Persist the settings through ISite/SiteSettings, the settings driver/view,
  the Settings recipe step, and the site settings deployment source.
- Render the selector in TheAdmin Pager view, preserving the query string.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ings UX

- Render the "Items per page" selector centrally in the Pager and PagerSlim
  shapes so it appears on both admin and front-end listings (including
  cursor-based PagerSlim lists such as blog posts) across all themes. When the
  feature is disabled (default), pagers render exactly as before.
- Honor the requested page size for ListPart listings (Pager and PagerSlim) and
  add an optional PageSize to PagerSlimParameters.
- Default PageSizeOptions to 10, 25, 50, 100.
- Settings: only show the "Page size options" field when selection is enabled,
  and validate the input (comma-separated positive integers), always storing a
  sorted, de-duplicated list.
- Add PagerOptions.GetPageSize(int?, int) overload for list-specific defaults.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…validate options against MaxPageSize

- Extract the inline page size selector markup into a dedicated
  Pager_PageSizeSelector shape with default templates in TheAdmin and
  TheTheme, so themes can customize it like the other pager sub-shapes.
  This also removes the IHtmlContent-returning BuildPageSizeSelector
  helper that tripped analyzer error CA1859 under --warnaserror.
- Reject page size options greater than the configurable MaxPageSize in
  the general settings validation, and surface the limit in the hint.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@gvkries

gvkries commented Sep 4, 2026

Copy link
Copy Markdown
Member

AFAIK, this also fixes an issue in the current implementation. MaxPageSize is currently ignored when a client specifies a page size via a query parameter, allowing requests for an arbitrary number of items in a single call. This effectively bypasses the configured limit and makes any paging endpoint a potential DoS attack vector. Setting the page size is also possible for anonymous users from the front end when using the full pager, which makes this issue even more concerning.

@gvkries

gvkries commented Sep 4, 2026

Copy link
Copy Markdown
Member

Should we also make the MaxPageSize site setting configurable from the admin dashboard?

@MikeAlhayek

Copy link
Copy Markdown
Member Author

@gvkries Agreed, this fixes that bug as well.

Currently, you can simply add ?pagenum=1&pagesize=1000 to the URL, and you'll get the maximum allowed page size, which is 1,000. There are no permissions or settings required for this to work, and yes, it can also be used by an anonymous user.

I'm not sure whether we should allow MaxPageSize to be edited. I believe this option was intended as an instance-level catch-all safeguard to prevent users—even administrators—from accidentally setting an excessively large page size and potentially hanging the instance.

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.

Allow Users to Select Records Per Page on Listing Pages

2 participants