mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-07-28 18:24:38 -05:00
Merge pull request #881 from paperless-ngx/feature-fix-saved-view-query-params
Feature / fix saved view & sort field query params
This commit is contained in:
@@ -22,6 +22,7 @@ import {
|
||||
RemoteVersionService,
|
||||
AppRemoteVersion,
|
||||
} from 'src/app/services/rest/remote-version.service'
|
||||
import { QueryParamsService } from 'src/app/services/query-params.service'
|
||||
|
||||
@Component({
|
||||
selector: 'app-app-frame',
|
||||
@@ -37,7 +38,8 @@ export class AppFrameComponent {
|
||||
public savedViewService: SavedViewService,
|
||||
private list: DocumentListViewService,
|
||||
private meta: Meta,
|
||||
private remoteVersionService: RemoteVersionService
|
||||
private remoteVersionService: RemoteVersionService,
|
||||
private queryParamsService: QueryParamsService
|
||||
) {
|
||||
this.remoteVersionService
|
||||
.checkForUpdates()
|
||||
@@ -92,7 +94,7 @@ export class AppFrameComponent {
|
||||
|
||||
search() {
|
||||
this.closeMenu()
|
||||
this.list.quickFilter([
|
||||
this.queryParamsService.navigateWithFilterRules([
|
||||
{
|
||||
rule_type: FILTER_FULLTEXT_QUERY,
|
||||
value: (this.searchField.value as string).trim(),
|
||||
|
@@ -3,11 +3,11 @@ import { Router } from '@angular/router'
|
||||
import { Subscription } from 'rxjs'
|
||||
import { PaperlessDocument } from 'src/app/data/paperless-document'
|
||||
import { PaperlessSavedView } from 'src/app/data/paperless-saved-view'
|
||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
|
||||
import { ConsumerStatusService } from 'src/app/services/consumer-status.service'
|
||||
import { DocumentService } from 'src/app/services/rest/document.service'
|
||||
import { PaperlessTag } from 'src/app/data/paperless-tag'
|
||||
import { FILTER_HAS_TAGS_ALL } from 'src/app/data/filter-rule-type'
|
||||
import { QueryParamsService } from 'src/app/services/query-params.service'
|
||||
|
||||
@Component({
|
||||
selector: 'app-saved-view-widget',
|
||||
@@ -18,7 +18,7 @@ export class SavedViewWidgetComponent implements OnInit, OnDestroy {
|
||||
constructor(
|
||||
private documentService: DocumentService,
|
||||
private router: Router,
|
||||
private list: DocumentListViewService,
|
||||
private queryParamsService: QueryParamsService,
|
||||
private consumerStatusService: ConsumerStatusService
|
||||
) {}
|
||||
|
||||
@@ -60,13 +60,14 @@ export class SavedViewWidgetComponent implements OnInit, OnDestroy {
|
||||
if (this.savedView.show_in_sidebar) {
|
||||
this.router.navigate(['view', this.savedView.id])
|
||||
} else {
|
||||
this.list.loadSavedView(this.savedView, true)
|
||||
this.router.navigate(['documents'])
|
||||
this.router.navigate(['documents'], {
|
||||
queryParams: { view: this.savedView.id },
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
clickTag(tag: PaperlessTag) {
|
||||
this.list.quickFilter([
|
||||
this.queryParamsService.navigateWithFilterRules([
|
||||
{ rule_type: FILTER_HAS_TAGS_ALL, value: tag.id.toString() },
|
||||
])
|
||||
}
|
||||
|
@@ -35,6 +35,7 @@ import {
|
||||
import { PaperlessDocumentSuggestions } from 'src/app/data/paperless-document-suggestions'
|
||||
import { FILTER_FULLTEXT_MORELIKE } from 'src/app/data/filter-rule-type'
|
||||
import { normalizeDateStr } from 'src/app/utils/date'
|
||||
import { QueryParamsService } from 'src/app/services/query-params.service'
|
||||
|
||||
@Component({
|
||||
selector: 'app-document-detail',
|
||||
@@ -114,7 +115,8 @@ export class DocumentDetailComponent
|
||||
private documentListViewService: DocumentListViewService,
|
||||
private documentTitlePipe: DocumentTitlePipe,
|
||||
private toastService: ToastService,
|
||||
private settings: SettingsService
|
||||
private settings: SettingsService,
|
||||
private queryParamsService: QueryParamsService
|
||||
) {
|
||||
this.titleSubject
|
||||
.pipe(
|
||||
@@ -446,7 +448,7 @@ export class DocumentDetailComponent
|
||||
}
|
||||
|
||||
moreLike() {
|
||||
this.documentListViewService.quickFilter([
|
||||
this.queryParamsService.navigateWithFilterRules([
|
||||
{
|
||||
rule_type: FILTER_FULLTEXT_MORELIKE,
|
||||
value: this.documentId.toString(),
|
||||
|
@@ -38,7 +38,7 @@
|
||||
<div ngbDropdown class="btn-group ms-2 flex-fill">
|
||||
<button class="btn btn-outline-primary btn-sm" id="dropdownBasic1" ngbDropdownToggle i18n>Sort</button>
|
||||
<div ngbDropdownMenu aria-labelledby="dropdownBasic1" class="shadow dropdown-menu-right">
|
||||
<div class="w-100 d-flex btn-group-toggle pb-2 mb-1 border-bottom" ngbRadioGroup [(ngModel)]="list.sortReverse">
|
||||
<div class="w-100 d-flex btn-group-toggle pb-2 mb-1 border-bottom" ngbRadioGroup [(ngModel)]="listSort">
|
||||
<label ngbButtonLabel class="btn-outline-primary btn-sm mx-2 flex-fill">
|
||||
<input ngbButton type="radio" class="btn btn-check btn-sm" [value]="false">
|
||||
<svg class="toolbaricon" fill="currentColor">
|
||||
@@ -53,7 +53,7 @@
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<button *ngFor="let f of getSortFields()" ngbDropdownItem (click)="list.sortField = f.field"
|
||||
<button *ngFor="let f of getSortFields()" ngbDropdownItem (click)="setSortField(f.field)"
|
||||
[class.active]="list.sortField == f.field">{{f.name}}
|
||||
</button>
|
||||
</div>
|
||||
@@ -64,7 +64,7 @@
|
||||
<button class="btn btn-sm btn-outline-primary dropdown-toggle flex-fill" ngbDropdownToggle i18n>Views</button>
|
||||
<div class="dropdown-menu shadow dropdown-menu-right" ngbDropdownMenu>
|
||||
<ng-container *ngIf="!list.activeSavedViewId">
|
||||
<button ngbDropdownItem *ngFor="let view of savedViewService.allViews" (click)="loadViewConfig(view)">{{view.name}}</button>
|
||||
<button ngbDropdownItem *ngFor="let view of savedViewService.allViews" (click)="loadViewConfig(view.id)">{{view.name}}</button>
|
||||
<div class="dropdown-divider" *ngIf="savedViewService.allViews.length > 0"></div>
|
||||
</ng-container>
|
||||
|
||||
|
@@ -9,20 +9,9 @@ import {
|
||||
} from '@angular/core'
|
||||
import { ActivatedRoute, Router } from '@angular/router'
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||
import {
|
||||
filter,
|
||||
first,
|
||||
map,
|
||||
Subject,
|
||||
Subscription,
|
||||
switchMap,
|
||||
takeUntil,
|
||||
} from 'rxjs'
|
||||
import { filter, first, map, Subject, switchMap, takeUntil } from 'rxjs'
|
||||
import { FilterRule, isFullTextFilterRule } from 'src/app/data/filter-rule'
|
||||
import {
|
||||
FILTER_FULLTEXT_MORELIKE,
|
||||
FILTER_RULE_TYPES,
|
||||
} from 'src/app/data/filter-rule-type'
|
||||
import { FILTER_FULLTEXT_MORELIKE } from 'src/app/data/filter-rule-type'
|
||||
import { PaperlessDocument } from 'src/app/data/paperless-document'
|
||||
import { PaperlessSavedView } from 'src/app/data/paperless-saved-view'
|
||||
import {
|
||||
@@ -32,7 +21,10 @@ import {
|
||||
import { ConsumerStatusService } from 'src/app/services/consumer-status.service'
|
||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
|
||||
import {
|
||||
DocumentService,
|
||||
filterRulesFromQueryParams,
|
||||
QueryParamsService,
|
||||
} from 'src/app/services/query-params.service'
|
||||
import {
|
||||
DOCUMENT_SORT_FIELDS,
|
||||
DOCUMENT_SORT_FIELDS_FULLTEXT,
|
||||
} from 'src/app/services/rest/document.service'
|
||||
@@ -49,13 +41,13 @@ import { SaveViewConfigDialogComponent } from './save-view-config-dialog/save-vi
|
||||
export class DocumentListComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
constructor(
|
||||
public list: DocumentListViewService,
|
||||
private documentService: DocumentService,
|
||||
public savedViewService: SavedViewService,
|
||||
public route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private toastService: ToastService,
|
||||
private modalService: NgbModal,
|
||||
private consumerStatusService: ConsumerStatusService
|
||||
private consumerStatusService: ConsumerStatusService,
|
||||
private queryParamsService: QueryParamsService
|
||||
) {}
|
||||
|
||||
@ViewChild('filterEditor')
|
||||
@@ -83,8 +75,26 @@ export class DocumentListComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
: DOCUMENT_SORT_FIELDS
|
||||
}
|
||||
|
||||
set listSort(reverse: boolean) {
|
||||
this.list.sortReverse = reverse
|
||||
this.queryParamsService.sortField = this.list.sortField
|
||||
this.queryParamsService.sortReverse = reverse
|
||||
}
|
||||
|
||||
get listSort(): boolean {
|
||||
return this.list.sortReverse
|
||||
}
|
||||
|
||||
setSortField(field: string) {
|
||||
this.list.sortField = field
|
||||
this.queryParamsService.sortField = field
|
||||
this.queryParamsService.sortReverse = this.listSort
|
||||
}
|
||||
|
||||
onSort(event: SortEvent) {
|
||||
this.list.setSort(event.column, event.reverse)
|
||||
this.queryParamsService.sortField = event.column
|
||||
this.queryParamsService.sortReverse = event.reverse
|
||||
}
|
||||
|
||||
get isBulkEditing(): boolean {
|
||||
@@ -109,60 +119,39 @@ export class DocumentListComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
|
||||
this.route.paramMap
|
||||
.pipe(
|
||||
filter((params) => params.has('id')), // only on saved view
|
||||
filter((params) => params.has('id')), // only on saved view e.g. /view/id
|
||||
switchMap((params) => {
|
||||
return this.savedViewService
|
||||
.getCached(+params.get('id'))
|
||||
.pipe(map((view) => ({ params, view })))
|
||||
.pipe(map((view) => ({ view })))
|
||||
})
|
||||
)
|
||||
.pipe(takeUntil(this.unsubscribeNotifier))
|
||||
.subscribe(({ view, params }) => {
|
||||
.subscribe(({ view }) => {
|
||||
if (!view) {
|
||||
this.router.navigate(['404'])
|
||||
return
|
||||
}
|
||||
this.list.activateSavedView(view)
|
||||
this.list.reload()
|
||||
this.queryParamsService.updateFromView(view)
|
||||
this.unmodifiedFilterRules = view.filter_rules
|
||||
})
|
||||
|
||||
const allFilterRuleQueryParams: string[] = FILTER_RULE_TYPES.map(
|
||||
(rt) => rt.filtervar
|
||||
)
|
||||
|
||||
this.route.queryParamMap
|
||||
.pipe(
|
||||
filter(() => !this.route.snapshot.paramMap.has('id')), // only when not on saved view
|
||||
filter(() => !this.route.snapshot.paramMap.has('id')), // only when not on /view/id
|
||||
takeUntil(this.unsubscribeNotifier)
|
||||
)
|
||||
.subscribe((queryParams) => {
|
||||
// transform query params to filter rules
|
||||
let filterRulesFromQueryParams: FilterRule[] = []
|
||||
allFilterRuleQueryParams
|
||||
.filter((frqp) => queryParams.has(frqp))
|
||||
.forEach((filterQueryParamName) => {
|
||||
const filterQueryParamValues: string[] = queryParams
|
||||
.get(filterQueryParamName)
|
||||
.split(',')
|
||||
|
||||
filterRulesFromQueryParams = filterRulesFromQueryParams.concat(
|
||||
// map all values to filter rules
|
||||
filterQueryParamValues.map((val) => {
|
||||
return {
|
||||
rule_type: FILTER_RULE_TYPES.find(
|
||||
(rt) => rt.filtervar == filterQueryParamName
|
||||
).id,
|
||||
value: val,
|
||||
}
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
this.list.activateSavedView(null)
|
||||
this.list.filterRules = filterRulesFromQueryParams
|
||||
this.list.reload()
|
||||
this.unmodifiedFilterRules = []
|
||||
if (queryParams.has('view')) {
|
||||
// loading a saved view on /documents
|
||||
this.loadViewConfig(parseInt(queryParams.get('view')))
|
||||
} else {
|
||||
this.list.activateSavedView(null)
|
||||
this.queryParamsService.parseQueryParams(queryParams)
|
||||
this.unmodifiedFilterRules = []
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -171,17 +160,7 @@ export class DocumentListComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
.pipe(takeUntil(this.unsubscribeNotifier))
|
||||
.subscribe({
|
||||
next: (filterRules) => {
|
||||
const params =
|
||||
this.documentService.filterRulesToQueryParams(filterRules)
|
||||
|
||||
// if we were on a saved view we navigate 'away' to /documents
|
||||
let base = []
|
||||
if (this.route.snapshot.paramMap.has('id')) base = ['/documents']
|
||||
|
||||
this.router.navigate(base, {
|
||||
relativeTo: this.route,
|
||||
queryParams: params,
|
||||
})
|
||||
this.queryParamsService.updateFilterRules(filterRules)
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -192,9 +171,15 @@ export class DocumentListComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
this.unsubscribeNotifier.complete()
|
||||
}
|
||||
|
||||
loadViewConfig(view: PaperlessSavedView) {
|
||||
this.list.loadSavedView(view)
|
||||
this.list.reload()
|
||||
loadViewConfig(viewId: number) {
|
||||
this.savedViewService
|
||||
.getCached(viewId)
|
||||
.pipe(first())
|
||||
.subscribe((view) => {
|
||||
this.list.loadSavedView(view)
|
||||
this.list.reload()
|
||||
this.queryParamsService.updateFromView(view)
|
||||
})
|
||||
}
|
||||
|
||||
saveViewConfig() {
|
||||
@@ -282,7 +267,7 @@ export class DocumentListComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
}
|
||||
|
||||
clickMoreLike(documentID: number) {
|
||||
this.list.quickFilter([
|
||||
this.queryParamsService.navigateWithFilterRules([
|
||||
{ rule_type: FILTER_FULLTEXT_MORELIKE, value: documentID.toString() },
|
||||
])
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@ import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { FILTER_CORRESPONDENT } from 'src/app/data/filter-rule-type'
|
||||
import { PaperlessCorrespondent } from 'src/app/data/paperless-correspondent'
|
||||
import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe'
|
||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
|
||||
import { QueryParamsService } from 'src/app/services/query-params.service'
|
||||
import { CorrespondentService } from 'src/app/services/rest/correspondent.service'
|
||||
import { ToastService } from 'src/app/services/toast.service'
|
||||
import { CorrespondentEditDialogComponent } from '../../common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component'
|
||||
@@ -20,7 +20,7 @@ export class CorrespondentListComponent extends ManagementListComponent<Paperles
|
||||
correspondentsService: CorrespondentService,
|
||||
modalService: NgbModal,
|
||||
toastService: ToastService,
|
||||
list: DocumentListViewService,
|
||||
queryParamsService: QueryParamsService,
|
||||
private datePipe: CustomDatePipe
|
||||
) {
|
||||
super(
|
||||
@@ -28,7 +28,7 @@ export class CorrespondentListComponent extends ManagementListComponent<Paperles
|
||||
modalService,
|
||||
CorrespondentEditDialogComponent,
|
||||
toastService,
|
||||
list,
|
||||
queryParamsService,
|
||||
FILTER_CORRESPONDENT,
|
||||
$localize`correspondent`,
|
||||
[
|
||||
|
@@ -2,7 +2,7 @@ import { Component } from '@angular/core'
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { FILTER_DOCUMENT_TYPE } from 'src/app/data/filter-rule-type'
|
||||
import { PaperlessDocumentType } from 'src/app/data/paperless-document-type'
|
||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
|
||||
import { QueryParamsService } from 'src/app/services/query-params.service'
|
||||
import { DocumentTypeService } from 'src/app/services/rest/document-type.service'
|
||||
import { ToastService } from 'src/app/services/toast.service'
|
||||
import { DocumentTypeEditDialogComponent } from '../../common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component'
|
||||
@@ -18,14 +18,14 @@ export class DocumentTypeListComponent extends ManagementListComponent<Paperless
|
||||
documentTypeService: DocumentTypeService,
|
||||
modalService: NgbModal,
|
||||
toastService: ToastService,
|
||||
list: DocumentListViewService
|
||||
queryParamsService: QueryParamsService
|
||||
) {
|
||||
super(
|
||||
documentTypeService,
|
||||
modalService,
|
||||
DocumentTypeEditDialogComponent,
|
||||
toastService,
|
||||
list,
|
||||
queryParamsService,
|
||||
FILTER_DOCUMENT_TYPE,
|
||||
$localize`document type`,
|
||||
[]
|
||||
|
@@ -18,7 +18,7 @@ import {
|
||||
SortableDirective,
|
||||
SortEvent,
|
||||
} from 'src/app/directives/sortable.directive'
|
||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
|
||||
import { QueryParamsService } from 'src/app/services/query-params.service'
|
||||
import { AbstractNameFilterService } from 'src/app/services/rest/abstract-name-filter-service'
|
||||
import { ToastService } from 'src/app/services/toast.service'
|
||||
import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component'
|
||||
@@ -42,7 +42,7 @@ export abstract class ManagementListComponent<T extends ObjectWithId>
|
||||
private modalService: NgbModal,
|
||||
private editDialogComponent: any,
|
||||
private toastService: ToastService,
|
||||
private list: DocumentListViewService,
|
||||
private queryParamsService: QueryParamsService,
|
||||
protected filterRuleType: number,
|
||||
public typeName: string,
|
||||
public extraColumns: ManagementListColumn[]
|
||||
@@ -140,7 +140,7 @@ export abstract class ManagementListComponent<T extends ObjectWithId>
|
||||
}
|
||||
|
||||
filterDocuments(object: ObjectWithId) {
|
||||
this.list.quickFilter([
|
||||
this.queryParamsService.navigateWithFilterRules([
|
||||
{ rule_type: this.filterRuleType, value: object.id.toString() },
|
||||
])
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@ import { Component } from '@angular/core'
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { FILTER_HAS_TAGS_ALL } from 'src/app/data/filter-rule-type'
|
||||
import { PaperlessTag } from 'src/app/data/paperless-tag'
|
||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
|
||||
import { QueryParamsService } from 'src/app/services/query-params.service'
|
||||
import { TagService } from 'src/app/services/rest/tag.service'
|
||||
import { ToastService } from 'src/app/services/toast.service'
|
||||
import { TagEditDialogComponent } from '../../common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component'
|
||||
@@ -18,14 +18,14 @@ export class TagListComponent extends ManagementListComponent<PaperlessTag> {
|
||||
tagService: TagService,
|
||||
modalService: NgbModal,
|
||||
toastService: ToastService,
|
||||
list: DocumentListViewService
|
||||
queryParamsService: QueryParamsService
|
||||
) {
|
||||
super(
|
||||
tagService,
|
||||
modalService,
|
||||
TagEditDialogComponent,
|
||||
toastService,
|
||||
list,
|
||||
queryParamsService,
|
||||
FILTER_HAS_TAGS_ALL,
|
||||
$localize`tag`,
|
||||
[
|
||||
|
Reference in New Issue
Block a user