mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-02-22 19:36:24 +00:00
Compare commits
4 Commits
feature-do
...
tweak-rese
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
342672d73e | ||
|
|
57c5939d7b | ||
|
|
43fe932c57 | ||
|
|
83f68d6063 |
@@ -1781,11 +1781,15 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/app-frame/app-frame.component.ts</context>
|
||||
<context context-type="linenumber">216</context>
|
||||
<context context-type="linenumber">156</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/app-frame/app-frame.component.ts</context>
|
||||
<context context-type="linenumber">241</context>
|
||||
<context context-type="linenumber">230</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/app-frame/app-frame.component.ts</context>
|
||||
<context context-type="linenumber">255</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2991443309752293110" datatype="html">
|
||||
@@ -3113,21 +3117,21 @@
|
||||
<source>Sidebar views updated</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/app-frame/app-frame.component.ts</context>
|
||||
<context context-type="linenumber">329</context>
|
||||
<context context-type="linenumber">343</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3547923076537026828" datatype="html">
|
||||
<source>Error updating sidebar views</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/app-frame/app-frame.component.ts</context>
|
||||
<context context-type="linenumber">332</context>
|
||||
<context context-type="linenumber">346</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2526035785704676448" datatype="html">
|
||||
<source>An error occurred while saving update checking settings.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/app-frame/app-frame.component.ts</context>
|
||||
<context context-type="linenumber">353</context>
|
||||
<context context-type="linenumber">367</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4580988005648117665" datatype="html">
|
||||
|
||||
@@ -243,9 +243,19 @@ describe('AppFrameComponent', () => {
|
||||
|
||||
it('should support toggling slim sidebar and saving', fakeAsync(() => {
|
||||
const saveSettingSpy = jest.spyOn(settingsService, 'set')
|
||||
settingsService.set(SETTINGS_KEYS.ATTRIBUTES_SECTIONS_COLLAPSED, [])
|
||||
expect(component.slimSidebarEnabled).toBeFalsy()
|
||||
expect(component.slimSidebarAnimating).toBeFalsy()
|
||||
component.toggleSlimSidebar()
|
||||
const requests = httpTestingController.match(
|
||||
`${environment.apiBaseUrl}ui_settings/`
|
||||
)
|
||||
expect(requests).toHaveLength(1)
|
||||
expect(requests[0].request.body.settings.slim_sidebar).toBe(true)
|
||||
expect(
|
||||
requests[0].request.body.settings.attributes_sections_collapsed
|
||||
).toEqual(['attributes'])
|
||||
requests[0].flush({ success: true })
|
||||
expect(component.slimSidebarAnimating).toBeTruthy()
|
||||
tick(200)
|
||||
expect(component.slimSidebarAnimating).toBeFalsy()
|
||||
@@ -254,6 +264,10 @@ describe('AppFrameComponent', () => {
|
||||
SETTINGS_KEYS.SLIM_SIDEBAR,
|
||||
true
|
||||
)
|
||||
expect(saveSettingSpy).toHaveBeenCalledWith(
|
||||
SETTINGS_KEYS.ATTRIBUTES_SECTIONS_COLLAPSED,
|
||||
['attributes']
|
||||
)
|
||||
}))
|
||||
|
||||
it('should show error on toggle slim sidebar if store settings fails', () => {
|
||||
|
||||
@@ -140,10 +140,24 @@ export class AppFrameComponent
|
||||
|
||||
toggleSlimSidebar(): void {
|
||||
this.slimSidebarAnimating = true
|
||||
this.slimSidebarEnabled = !this.slimSidebarEnabled
|
||||
if (this.slimSidebarEnabled) {
|
||||
this.attributesSectionsCollapsed = true
|
||||
const slimSidebarEnabled = !this.slimSidebarEnabled
|
||||
this.settingsService.set(SETTINGS_KEYS.SLIM_SIDEBAR, slimSidebarEnabled)
|
||||
if (slimSidebarEnabled) {
|
||||
this.settingsService.set(SETTINGS_KEYS.ATTRIBUTES_SECTIONS_COLLAPSED, [
|
||||
CollapsibleSection.ATTRIBUTES,
|
||||
])
|
||||
}
|
||||
this.settingsService
|
||||
.storeSettings()
|
||||
.pipe(first())
|
||||
.subscribe({
|
||||
error: (error) => {
|
||||
this.toastService.showError(
|
||||
$localize`An error occurred while saving settings.`
|
||||
)
|
||||
console.warn(error)
|
||||
},
|
||||
})
|
||||
setTimeout(() => {
|
||||
this.slimSidebarAnimating = false
|
||||
}, 200) // slightly longer than css animation for slim sidebar
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
</pngx-page-header>
|
||||
|
||||
<div class="row sticky-top py-3 mt-n2 mt-md-n3 bg-body">
|
||||
<pngx-filter-editor [hidden]="isBulkEditing" [disabled]="isBulkEditing" [(filterRules)]="list.filterRules" [unmodifiedFilterRules]="unmodifiedFilterRules" [selectionData]="list.selectionData" #filterEditor></pngx-filter-editor>
|
||||
<pngx-filter-editor [hidden]="isBulkEditing" [disabled]="isBulkEditing" [filterRules]="list.filterRules" (filterRulesChange)="onFilterRulesChange($event)" (resetFilterRules)="onFilterRulesReset($event)" [unmodifiedFilterRules]="unmodifiedFilterRules" [selectionData]="list.selectionData" #filterEditor></pngx-filter-editor>
|
||||
<pngx-bulk-editor [hidden]="!isBulkEditing" [disabled]="!isBulkEditing"></pngx-bulk-editor>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -1101,6 +1101,9 @@ export class FilterEditorComponent
|
||||
@Output()
|
||||
filterRulesChange = new EventEmitter<FilterRule[]>()
|
||||
|
||||
@Output()
|
||||
resetFilterRules = new EventEmitter<FilterRule[]>()
|
||||
|
||||
@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) {
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -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'])
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ class Migration(migrations.Migration):
|
||||
name="stop_processing",
|
||||
field=models.BooleanField(
|
||||
default=False,
|
||||
help_text="If True, no further rules will be processed after this one if any document is consumed.",
|
||||
help_text="If True, no further rules will be processed after this one if any document is queued.",
|
||||
verbose_name="Stop processing further rules",
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user