Cleanups from a code-simplification pass over the prior commit:
- Extract the repeated "build HttpParams from a plain object, skipping
null/undefined" loop (previously duplicated in list(), getFew(), and the
new getFilterSelectionData()) into a single shared
AbstractPaperlessService.withParams() helper.
- document-list-view.service.ts: fire the filter_selection_data request
concurrently with the primary list request instead of nesting it inside
the list request's success callback. They're independent (the follow-up
only needs filterRules, not the list response), so there's no reason to
wait on one before starting the other. Extracted into
loadFilterSelectionData() for readability, and guarded the error path so
a failed list request cancels the concurrent follow-up too rather than
letting it resolve afterward and clobber the error-state reset.
- views.py: give filter_selection_data a lean base queryset
(_base_document_queryset) instead of the full get_queryset(), which
carries select_related/prefetch_related meant for serializing full
Document objects. Benchmarked this specifically: no measured query-time
impact in this path, since those calls were never iterating the
queryset directly and were already inert here -- keeping it for
clarity, not as a performance claim.
- Test fallout: since filter_selection_data now fires unconditionally on
every non-search reload() rather than only after a successful primary
flush, added a generic drain step to both spec files' afterEach so
individual tests don't each need to know about this follow-up request
unless they specifically assert on its response.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The document overview sent include_selection_data=true on every list
request (page/filter/sort change), computing 5 correlated Count(DISTINCT)
aggregations over the full matching queryset inline before the list could
render. At scale (hundreds of thousands of documents, unfiltered) this is
the confirmed root cause of the document overview "eternally loading" in
paperless-ngx/paperless-ngx#13161.
Split the aggregation into its own endpoint, GET
/api/documents/filter_selection_data/, filter-scoped the same way the
list endpoint already resolves matches (no document ID enumeration
needed). The frontend now fetches it as a separate, non-blocking request
after the list has already rendered, for plain (non-search) browsing.
Full-text search keeps computing it inline since results are already
narrowed by the search backend first.
include_selection_data never shipped in a stable release (introduced
this beta cycle, not present on main), so the plain list endpoint simply
stops acting on it rather than needing a deprecation path.
Also closes a latent localStorage leak between
document-list-view.service.spec.ts tests (filterRules persisted via
localStorage were never cleared, only sessionStorage was) that this
change's new URL-dependent follow-up request exposed, and fixes two
tests that were unknowingly relying on that leaked state to pass.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>