Skip to content

Chore/server pagination#565

Merged
dcharles525 merged 8 commits intofeat/EPINIO-523-524__services_catalogfrom
chore/server_pagination
Apr 17, 2026
Merged

Chore/server pagination#565
dcharles525 merged 8 commits intofeat/EPINIO-523-524__services_catalogfrom
chore/server_pagination

Conversation

@Hannahbird
Copy link
Copy Markdown
Contributor

@Hannahbird Hannahbird commented Apr 16, 2026

PR Checklist

  • Linting Test is passing
  • Code is well documented
  • If applicable, a PR in the epinio/docs repository has been opened

Summary

Fixes #

Adds server-side pagination support across all Epinio list tables (configurations, services, namespaces, app charts) and per-namespace pagination for the applications view. The trailhand-table page-change event is now consumed by each list component, which dispatches to a new Vuex goToPage action that re-fetches the correct page from the API.

Occurred changes and/or fixed issues

  • Store (epinio-store): added paginationPage and paginationMeta state slices, setPaginationPage / setPaginationMeta mutations, urlOptions getter that injects page / pageSize query params into API URLs automatically, paginationMeta and currentPaginationPage getters, goToPage action, and findAppsInNamespace action for per-namespace fetches that bypass global meta.
  • request action: detects paginated API responses (shape { items, page, pageSize, totalItems, totalPages }), commits setPaginationMeta, and returns _pagination alongside row data. Callers can opt out via _skipPaginationMeta.
  • All list tables (configurations, services, namespaces, appcharts): read paginationMeta from the store, pass :server-side, :total-items, and :current-page props to trailhand-table, and handle @page-change by calling goToPage.
  • Applications index page: uses a two-phase strategy. One global findAll (no page params) for instant initial render, followed by silent per-namespace background fetches to seed pagination meta. Subsequent @page-change events trigger per-namespace refetches without a global loading overlay.

Technical notes summary

  • urlOptions acts as a transparent middleware: any urlFor call for a known type (/api/v1/appcharts, /api/v1/namespaces, /api/v1/configurations, /api/v1/services) automatically receives current page params from store state, so no component needs to manually construct paginated URLs.
  • The applications page deliberately avoids using urlOptions for its per-namespace calls. It builds the URL directly with the namespace path and _skipPaginationMeta: true to keep each namespace table's meta isolated from the global pagination state.
  • goToPage is a simple two-step: commit the new page number to state (which urlOptions will read), then force a findAll refetch.
  • Before this PR, trailhand-table had no page-change event. The Lit component's goToPage method was updated upstream to dispatchEvent(new CustomEvent('page-change', { detail: { page }, bubbles: true, composed: true })).

Areas or cases that should be tested

  • Each list view (Configurations, Services, Namespaces, App Charts): navigate to page 2+, confirm the correct rows load and the URL sent to the API includes the right page and pageSize params.
  • Applications view: verify initial load shows rows immediately from global data, then per-namespace pagination controls appear once background meta fetch completes. Navigate between pages within a namespace without affecting other namespace tables.
  • Namespace filter: switch namespace filter while on page 2 of a list and confirm the table resets to page 1.
  • Empty / last page: confirm behavior when a page has fewer than 10 items (last page) or zero items.
  • Browser tested locally:

Areas which could experience regressions

  • Any list table that calls urlFor: urlOptions now silently appends page/pageSize for the four registered paths. If a type shares a URL path prefix with those paths, it could inadvertently get pagination params.
  • request action response parsing: the new branch that detects items array shape changes the res.data structure for paginated responses. Any code that previously destructured res.data directly (expecting a flat array) from those endpoints may break.
  • Applications global findAll: this call intentionally has no page params (returns all apps for namespace grouping). Confirm urlOptions does not inject params for /api/v1/applications (it is not in the pathToType map).
  • Polling: startPolling triggers findAll in the background. Confirm these background re-fetches respect the current paginationPage state rather than resetting to page 1.

Screenshot/Video

- Add pagination state (page, meta) to epinio store with setPaginationPage
  and setPaginationMeta mutations and goToPage action
- Inject page/pageSize query params via urlOptions for appcharts, namespaces,
  configurations, and services; apps intentionally excluded pending backend
  support for per-namespace pagination
- Wire trailhand-table server-side props (server-side, total-items,
  current-page, loading, page-change) to all list pages
- Applications page fetches all apps in one unpaginated call and groups
  by namespace alphabetically; empty namespace tables hidden
- Add findAppsInNamespace action for future per-namespace pagination
  once backend adds support
Now that the backend supports ?page&pageSize on the namespace applications
endpoint, fetch page 1 per namespace silently on mount to seed pagination
meta, then drive each namespace table independently on page-change events.
Global findAll still seeds instant initial display with no page params.
Copy link
Copy Markdown
Member

@dcharles525 dcharles525 left a comment

Choose a reason for hiding this comment

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

LGTM

@dcharles525 dcharles525 merged commit 29d3741 into feat/EPINIO-523-524__services_catalog Apr 17, 2026
2 checks passed
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.

2 participants