From d6cd6d031194bf17bc1f3179f249dbddbdbe006f Mon Sep 17 00:00:00 2001
From: shamoon <4887959+shamoon@users.noreply.github.com>
Date: Sun, 22 Feb 2026 15:17:02 -0800
Subject: [PATCH] Tweakhancement: reset to page 1 on reset filters (#12143)
---
.../document-list.component.html | 2 +-
.../document-list.component.spec.ts | 28 ++++++++---
.../document-list/document-list.component.ts | 10 +++-
.../filter-editor.component.spec.ts | 16 +++++++
.../filter-editor/filter-editor.component.ts | 5 +-
.../document-list-view.service.spec.ts | 46 +++++++++++++++----
.../services/document-list-view.service.ts | 7 ++-
7 files changed, 93 insertions(+), 21 deletions(-)
diff --git a/src-ui/src/app/components/document-list/document-list.component.html b/src-ui/src/app/components/document-list/document-list.component.html
index 18c4a2fcc..7fd1dc7fc 100644
--- a/src-ui/src/app/components/document-list/document-list.component.html
+++ b/src-ui/src/app/components/document-list/document-list.component.html
@@ -117,7 +117,7 @@
diff --git a/src-ui/src/app/components/document-list/document-list.component.spec.ts b/src-ui/src/app/components/document-list/document-list.component.spec.ts
index 87a6ee0a1..5dc9516a7 100644
--- a/src-ui/src/app/components/document-list/document-list.component.spec.ts
+++ b/src-ui/src/app/components/document-list/document-list.component.spec.ts
@@ -147,21 +147,21 @@ describe('DocumentListComponent', () => {
})
it('should show score sort fields on fulltext queries', () => {
- documentListService.filterRules = [
+ documentListService.setFilterRules([
{
rule_type: FILTER_HAS_TAGS_ANY,
value: '10',
},
- ]
+ ])
fixture.detectChanges()
expect(component.getSortFields()).toEqual(documentListService.sortFields)
- documentListService.filterRules = [
+ documentListService.setFilterRules([
{
rule_type: FILTER_FULLTEXT_QUERY,
value: 'foo',
},
- ]
+ ])
fixture.detectChanges()
expect(component.getSortFields()).toEqual(
documentListService.sortFieldsFullText
@@ -170,12 +170,12 @@ describe('DocumentListComponent', () => {
it('should determine if filtered, support reset', () => {
fixture.detectChanges()
- documentListService.filterRules = [
+ documentListService.setFilterRules([
{
rule_type: FILTER_HAS_TAGS_ANY,
value: '10',
},
- ]
+ ])
documentListService.isReloading = false
fixture.detectChanges()
expect(component.isFiltered).toBeTruthy()
@@ -185,6 +185,20 @@ describe('DocumentListComponent', () => {
expect(fixture.nativeElement.textContent.match(/Reset/g)).toHaveLength(1)
})
+ it('should apply filter rule changes via list service', () => {
+ const setFilterRulesSpy = jest.spyOn(documentListService, 'setFilterRules')
+ const rules = [{ rule_type: FILTER_HAS_TAGS_ANY, value: '10' }]
+ component.onFilterRulesChange(rules)
+ expect(setFilterRulesSpy).toHaveBeenCalledWith(rules)
+ })
+
+ it('should reset filter rules to page one via list service', () => {
+ const setFilterRulesSpy = jest.spyOn(documentListService, 'setFilterRules')
+ const rules = [{ rule_type: FILTER_HAS_TAGS_ANY, value: '10' }]
+ component.onFilterRulesReset(rules)
+ expect(setFilterRulesSpy).toHaveBeenCalledWith(rules, true)
+ })
+
it('should load saved view from URL', () => {
const view: SavedView = {
id: 10,
@@ -217,7 +231,7 @@ describe('DocumentListComponent', () => {
.spyOn(activatedRoute, 'paramMap', 'get')
.mockReturnValue(of(convertToParamMap(queryParams)))
activatedRoute.snapshot.queryParams = queryParams
- fixture.detectChanges()
+ component.ngOnInit()
expect(getSavedViewSpy).toHaveBeenCalledWith(view.id)
expect(activateSavedViewSpy).toHaveBeenCalledWith(
view,
diff --git a/src-ui/src/app/components/document-list/document-list.component.ts b/src-ui/src/app/components/document-list/document-list.component.ts
index d2d21ee17..c0dd8f80a 100644
--- a/src-ui/src/app/components/document-list/document-list.component.ts
+++ b/src-ui/src/app/components/document-list/document-list.component.ts
@@ -212,6 +212,14 @@ export class DocumentListComponent
this.list.setSort(event.column, event.reverse)
}
+ onFilterRulesChange(filterRules: FilterRule[]) {
+ this.list.setFilterRules(filterRules)
+ }
+
+ onFilterRulesReset(filterRules: FilterRule[]) {
+ this.list.setFilterRules(filterRules, true)
+ }
+
get isBulkEditing(): boolean {
return this.list.selected.size > 0
}
@@ -300,7 +308,7 @@ export class DocumentListComponent
if (this.list.selected.size > 0) {
this.list.selectNone()
} else if (this.isFiltered) {
- this.filterEditor.resetSelected()
+ this.resetFilters()
}
})
diff --git a/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.spec.ts b/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.spec.ts
index 39e58aefd..bf5240f1b 100644
--- a/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.spec.ts
+++ b/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.spec.ts
@@ -2107,6 +2107,22 @@ describe('FilterEditorComponent', () => {
expect(component.filterRules).toEqual(rules)
})
+ it('should emit reset filter rules when resetting', () => {
+ const rules = [{ rule_type: FILTER_HAS_TAGS_ANY, value: '2' }]
+ component.unmodifiedFilterRules = rules
+ component.filterRules = [
+ { rule_type: FILTER_DOES_NOT_HAVE_TAG, value: '2' },
+ ]
+
+ const resetFilterRulesSpy = jest.spyOn(component.resetFilterRules, 'next')
+ const filterRulesChangeSpy = jest.spyOn(component.filterRulesChange, 'next')
+
+ component.resetSelected()
+
+ expect(resetFilterRulesSpy).toHaveBeenCalledWith(rules)
+ expect(filterRulesChangeSpy).not.toHaveBeenCalled()
+ })
+
it('should support resetting text field', () => {
component.textFilter = 'foo'
component.resetTextField()
diff --git a/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.ts b/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.ts
index 55bb67d15..b717c13fc 100644
--- a/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.ts
+++ b/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.ts
@@ -1101,6 +1101,9 @@ export class FilterEditorComponent
@Output()
filterRulesChange = new EventEmitter()
+ @Output()
+ resetFilterRules = new EventEmitter()
+
@Input()
set selectionData(selectionData: SelectionData) {
this.tagDocumentCounts = selectionData?.selected_tags ?? null
@@ -1244,7 +1247,7 @@ export class FilterEditorComponent
this.textFilterTarget = TEXT_FILTER_TARGET_TITLE_CONTENT
this.documentService.searchQuery = ''
this.filterRules = this._unmodifiedFilterRules
- this.updateRules()
+ this.resetFilterRules.next(this.filterRules)
}
toggleTag(tagId: number) {
diff --git a/src-ui/src/app/services/document-list-view.service.spec.ts b/src-ui/src/app/services/document-list-view.service.spec.ts
index fdbfa2069..6258c42b2 100644
--- a/src-ui/src/app/services/document-list-view.service.spec.ts
+++ b/src-ui/src/app/services/document-list-view.service.spec.ts
@@ -164,7 +164,7 @@ describe('DocumentListViewService', () => {
value: tags__id__in,
},
]
- documentListViewService.filterRules = filterRulesAny
+ documentListViewService.setFilterRules(filterRulesAny)
let req = httpTestingController.expectOne(
`${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&tags__id__in=${tags__id__in}`
)
@@ -178,7 +178,7 @@ describe('DocumentListViewService', () => {
)
expect(req.request.method).toEqual('GET')
// reset the list
- documentListViewService.filterRules = []
+ documentListViewService.setFilterRules([])
req = httpTestingController.expectOne(
`${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true`
)
@@ -210,7 +210,7 @@ describe('DocumentListViewService', () => {
value: tags__id__in,
},
]
- documentListViewService.filterRules = filterRulesAny
+ documentListViewService.setFilterRules(filterRulesAny)
let req = httpTestingController.expectOne(
`${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&tags__id__in=${tags__id__in}`
)
@@ -218,7 +218,7 @@ describe('DocumentListViewService', () => {
req.flush('Generic error', { status: 404, statusText: 'Unexpected error' })
expect(documentListViewService.error).toEqual('Generic error')
// reset the list
- documentListViewService.filterRules = []
+ documentListViewService.setFilterRules([])
req = httpTestingController.expectOne(
`${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true`
)
@@ -295,13 +295,41 @@ describe('DocumentListViewService', () => {
})
it('should use filter rules to update query params', () => {
- documentListViewService.filterRules = filterRules
+ documentListViewService.setFilterRules(filterRules)
const req = httpTestingController.expectOne(
`${environment.apiBaseUrl}documents/?page=${documentListViewService.currentPage}&page_size=${documentListViewService.pageSize}&ordering=-created&truncate_content=true&tags__id__all=${tags__id__all}`
)
expect(req.request.method).toEqual('GET')
})
+ it('should support setting filter rules and resetting to page one', () => {
+ documentListViewService.currentPage = 2
+ let req = httpTestingController.expectOne((request) =>
+ request.urlWithParams.startsWith(
+ `${environment.apiBaseUrl}documents/?page=2&page_size=50&ordering=-created&truncate_content=true`
+ )
+ )
+ expect(req.request.method).toEqual('GET')
+ req.flush(full_results)
+ req = httpTestingController.expectOne(
+ `${environment.apiBaseUrl}documents/selection_data/`
+ )
+ req.flush([])
+
+ documentListViewService.setFilterRules(filterRules, true)
+
+ const filteredReqs = httpTestingController.match(
+ `${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&tags__id__all=${tags__id__all}`
+ )
+ expect(filteredReqs).toHaveLength(1)
+ filteredReqs[0].flush(full_results)
+ req = httpTestingController.expectOne(
+ `${environment.apiBaseUrl}documents/selection_data/`
+ )
+ req.flush([])
+ expect(documentListViewService.currentPage).toEqual(1)
+ })
+
it('should support quick filter', () => {
documentListViewService.quickFilter(filterRules)
const req = httpTestingController.expectOne(
@@ -336,7 +364,7 @@ describe('DocumentListViewService', () => {
req = httpTestingController.expectOne(
`${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-added&truncate_content=true&tags__id__all=9`
)
- documentListViewService.filterRules = []
+ documentListViewService.setFilterRules([])
req = httpTestingController.expectOne(
`${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-added&truncate_content=true`
)
@@ -348,7 +376,7 @@ describe('DocumentListViewService', () => {
})
it('should support navigating next / previous', () => {
- documentListViewService.filterRules = []
+ documentListViewService.setFilterRules([])
let req = httpTestingController.expectOne(
`${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true`
)
@@ -558,7 +586,7 @@ describe('DocumentListViewService', () => {
req.flush(full_results)
expect(documentListViewService.selected.size).toEqual(6)
- documentListViewService.filterRules = filterRules
+ documentListViewService.setFilterRules(filterRules)
httpTestingController.expectOne(
`${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true&tags__id__all=9`
)
@@ -592,7 +620,7 @@ describe('DocumentListViewService', () => {
documentListViewService.loadSavedView(view2)
expect(documentListViewService.sortField).toEqual('score')
- documentListViewService.filterRules = []
+ documentListViewService.setFilterRules([])
expect(documentListViewService.sortField).toEqual('created')
httpTestingController.expectOne(
`${environment.apiBaseUrl}documents/?page=1&page_size=50&ordering=-created&truncate_content=true`
diff --git a/src-ui/src/app/services/document-list-view.service.ts b/src-ui/src/app/services/document-list-view.service.ts
index 0bc43b782..6989db8ed 100644
--- a/src-ui/src/app/services/document-list-view.service.ts
+++ b/src-ui/src/app/services/document-list-view.service.ts
@@ -342,7 +342,7 @@ export class DocumentListViewService {
})
}
- set filterRules(filterRules: FilterRule[]) {
+ setFilterRules(filterRules: FilterRule[], resetPage: boolean = false) {
if (
!isFullTextFilterRule(filterRules) &&
this.activeListViewState.sortField == 'score'
@@ -350,6 +350,9 @@ export class DocumentListViewService {
this.activeListViewState.sortField = 'created'
}
this.activeListViewState.filterRules = filterRules
+ if (resetPage) {
+ this.activeListViewState.currentPage = 1
+ }
this.reload()
this.reduceSelectionToFilter()
this.saveDocumentListView()
@@ -479,7 +482,7 @@ export class DocumentListViewService {
quickFilter(filterRules: FilterRule[]) {
this._activeSavedViewId = null
- this.filterRules = filterRules
+ this.setFilterRules(filterRules)
this.router.navigate(['documents'])
}