Skip to content

POC feat: move filters and sorting to backend - #2855

Draft
Koc wants to merge 11 commits into
mainfrom
feature/backend-sorting-and-filtering
Draft

POC feat: move filters and sorting to backend#2855
Koc wants to merge 11 commits into
mainfrom
feature/backend-sorting-and-filtering

Conversation

@Koc

@Koc Koc commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

This PR is implemented on top of #1565. It contains all possible functionality added in V2. It moves table row listing, filtering, sorting and search to the backend so large tables can paginate without double-renders or stale page numbers.

I will try to extract some independent parts to separate PRs to simplify code review process.

image

What changed

  • Backend-powered pagination, filtering, sorting and search via v2 OCS endpoints for tables, views and public shares: GET /api/2/{tables|views}/{nodeId}/rows, .../rows/count and .../rows/export, plus GET /api/2/public/{token}/rows, .../rows/count and .../rows/export. Only the requested page is loaded, and client-side sorting/filtering in the table grid is now removed completely.
  • Column sort eligibility is now driven by a BACKEND_SORTABLE_TYPES allow-list in the frontend; only text-line, text-link, selection, selection-multi, number, number-stars, number-progress, datetime-date, datetime-time and datetime columns show the sorting UI.
  • Table and view state (filters, sorting, search, page, rows per page and selected row IDs) is persisted in the URL query string, so links can be shared with a predefined state. Example url https://nextcloud.test/apps/tables/#/table/9?filter=[{%22columnId%22:47,%22operator%22:%22contains%22,%22value%22:%22Sa%22}]&search=en&page=2&perPage=25
  • Selected rows can be shared via a rowIds URL query parameter. The selection menu has a "Share selected rows" action that copies a shareable link and temporarily shows an "Open" button. Example url https://nextcloud.test/apps/tables/#/table/9?rowIds=4025%2C3970%2C3989
  • CSV export now uses a dedicated .../rows/export endpoint (private and public); the backend builds the CSV from all matching rows (with filters, sort, search and rowIds) and returns it as a file.
  • Backend case-insensitive text search across raw stored cell values.
  • Text filters (contains, does-not-contain, begins-with, ends-with) are currently case-sensitive; case-insensitive filter matching is implemented in Fix: Make case-insensitive search for the view filters #2816.
  • Backend support for the "contains items" filter on selection columns, including multi-selection.
  • New reload/refresh button in the table header with a loading spinner; the empty state is shown when no rows match.
  • Pagination resets to page 1 on filter/search changes and stays in sync with the table.

Known limitations

  • Backend search currently matches the raw stored cell values, so for selection, usergroup and relation columns it matches option/user/relation IDs, not the visible labels.
  • Full-text search no longer highlights the matching cell in the row, since the backend does not return which cell matched.
  • Backend sort is not type-cast: number and number subtypes sort lexicographically (so e.g. 9 > 100), and datetime values are sorted as raw strings.
  • selection / selection-multi sort by raw option ID, not by option label.
  • usergroup and relation columns sort by raw user/row IDs, not by display labels, and selection-check / text-long / text-rich are not guarded from sorting.
  • Filter contains / does-not-contain on text-long / text-rich searches raw stored values (possibly with HTML for rich text) rather than visible text.
  • Search and filter result cell highlighting is not wired in the new backend flow: TableRow.vue currently has 'search-result': false and 'filter-result': false with no backend signal indicating which cell matched.

What to test

  • Tables and views with more rows than the page size: page size, page numbers and the row count.
  • Filters of all types, especially selection "contains items".
  • Search on text and number columns.
  • Pagination reset when adding, changing or clearing filters and search.
  • Loading spinner on the reload button and the empty state.
  • Opening a table or view with a rowIds query parameter and confirming only the selected rows are loaded.
  • The "Share selected rows" action: copied URL, temporary "Open" button, and reset clearing the selection.
  • CSV export for selected rows and filtered rows.

🗒️ TODO

  • Add Behat tests
  • Add Cypress tests

🏁 Checklist

  • ⛑️ Tests (unit and/or integration) are included or not needed
  • 🔙 Backport requests are created or not needed: /backport to stableX.X
  • 📅 Milestone is set
  • 🌸 PR title is meaningful (if it should be in the changelog: is it meaningful to users?)

🤖 AI (if applicable)

  • The content of this PR was partly or fully generated using AI

blizzz and others added 5 commits August 23, 2026 19:29
- also changes Api Route definition to attribute

Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
Signed-off-by: Kostiantyn Miakshyn <molodchick@gmail.com>
Signed-off-by: Kostiantyn Miakshyn <molodchick@gmail.com>
Signed-off-by: Kostiantyn Miakshyn <molodchick@gmail.com>
Signed-off-by: Kostiantyn Miakshyn <molodchick@gmail.com>
@Koc
Koc changed the base branch from feature/share-rows to main August 23, 2026 22:42
Signed-off-by: Kostiantyn Miakshyn <molodchick@gmail.com>
@Koc
Koc force-pushed the feature/backend-sorting-and-filtering branch 2 times, most recently from 2b87c72 to b0d85e7 Compare August 23, 2026 23:51
@Koc Koc changed the title feat: move filters and sorting to backend POC feat: move filters and sorting to backend Aug 24, 2026
@Koc
Koc force-pushed the feature/backend-sorting-and-filtering branch from b0d85e7 to 76efebb Compare August 24, 2026 00:10
Signed-off-by: Kostiantyn Miakshyn <molodchick@gmail.com>
case BEGINS_WITH = 'begins-with';
case ENDS_WITH = 'ends-with';
case CONTAINS = 'contains';
case CONTAINS_ITEM = 'contains-item';

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

do we need to move that into separate PR?

Koc added 3 commits August 24, 2026 02:29
Signed-off-by: Kostiantyn Miakshyn <molodchick@gmail.com>
Signed-off-by: Kostiantyn Miakshyn <molodchick@gmail.com>
Signed-off-by: Kostiantyn Miakshyn <molodchick@gmail.com>
@Koc
Koc force-pushed the feature/backend-sorting-and-filtering branch from 76efebb to c2e7efb Compare August 24, 2026 00:47
Signed-off-by: Kostiantyn Miakshyn <molodchick@gmail.com>
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.

2 participants