]> git.ipfire.org Git - thirdparty/paperless-ngx.git/commitdiff
Refactor query param handling to service
authorMichael Shamoon <4887959+shamoon@users.noreply.github.com>
Thu, 5 May 2022 07:23:06 +0000 (00:23 -0700)
committerMichael Shamoon <4887959+shamoon@users.noreply.github.com>
Thu, 5 May 2022 07:23:06 +0000 (00:23 -0700)
src-ui/src/app/components/app-frame/app-frame.component.ts
src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.ts
src-ui/src/app/components/document-detail/document-detail.component.ts
src-ui/src/app/components/document-list/document-list.component.ts
src-ui/src/app/components/manage/correspondent-list/correspondent-list.component.ts
src-ui/src/app/components/manage/document-type-list/document-type-list.component.ts
src-ui/src/app/components/manage/management-list/management-list.component.ts
src-ui/src/app/components/manage/tag-list/tag-list.component.ts
src-ui/src/app/services/document-list-view.service.ts
src-ui/src/app/services/query-params.service.ts [new file with mode: 0644]
src-ui/src/app/services/rest/document.service.ts

index a335aad1d9abb4982c248353e55f6d526f46a39b..4bab42cb02d127ae8e5adfc78cd0245cedb27374 100644 (file)
@@ -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.loadFilterRules([
       {
         rule_type: FILTER_FULLTEXT_QUERY,
         value: (this.searchField.value as string).trim(),
index b8bf389dd25ff167948c261f1654b8a6d5779f6d..20cd5aa9979d115a870efef74e6795f5b38b044c 100644 (file)
@@ -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
   ) {}
 
@@ -67,7 +67,7 @@ export class SavedViewWidgetComponent implements OnInit, OnDestroy {
   }
 
   clickTag(tag: PaperlessTag) {
-    this.list.quickFilter([
+    this.queryParamsService.loadFilterRules([
       { rule_type: FILTER_HAS_TAGS_ALL, value: tag.id.toString() },
     ])
   }
index 9b223f22abde7a71dfed857602b791c4a99f1c5c..1961c5e9f4e1440a658c76ed568c3149795e114a 100644 (file)
@@ -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.loadFilterRules([
       {
         rule_type: FILTER_FULLTEXT_MORELIKE,
         value: this.documentId.toString(),
index bfbf0fc47c681dedf7d5afe3cac4e528386fe904..8f8a0f6fc56c037029d4ac8904a54f0c8d82b4e7 100644 (file)
@@ -31,6 +31,7 @@ import {
 } from 'src/app/directives/sortable.directive'
 import { ConsumerStatusService } from 'src/app/services/consumer-status.service'
 import { DocumentListViewService } from 'src/app/services/document-list-view.service'
+import { QueryParamsService } from 'src/app/services/query-params.service'
 import {
   DocumentService,
   DOCUMENT_SORT_FIELDS,
@@ -55,7 +56,8 @@ export class DocumentListComponent implements OnInit, OnDestroy, AfterViewInit {
     private router: Router,
     private toastService: ToastService,
     private modalService: NgbModal,
-    private consumerStatusService: ConsumerStatusService
+    private consumerStatusService: ConsumerStatusService,
+    private queryParamsService: QueryParamsService
   ) {}
 
   @ViewChild('filterEditor')
@@ -127,10 +129,6 @@ export class DocumentListComponent implements OnInit, OnDestroy, AfterViewInit {
         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
@@ -140,30 +138,9 @@ export class DocumentListComponent implements OnInit, OnDestroy, AfterViewInit {
         if (queryParams.has('view')) {
           this.loadViewConfig(parseInt(queryParams.get('view')))
         } else {
-          // 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.queryParamsService.params = queryParams
+          this.list.filterRules = this.queryParamsService.filterRules
           this.list.reload()
           this.unmodifiedFilterRules = []
         }
@@ -175,8 +152,7 @@ export class DocumentListComponent implements OnInit, OnDestroy, AfterViewInit {
       .pipe(takeUntil(this.unsubscribeNotifier))
       .subscribe({
         next: (filterRules) => {
-          const params =
-            this.documentService.filterRulesToQueryParams(filterRules)
+          this.queryParamsService.filterRules = filterRules
 
           // if we were on a saved view we navigate 'away' to /documents
           let base = []
@@ -184,7 +160,7 @@ export class DocumentListComponent implements OnInit, OnDestroy, AfterViewInit {
 
           this.router.navigate(base, {
             relativeTo: this.route,
-            queryParams: params,
+            queryParams: this.queryParamsService.params,
           })
         },
       })
@@ -296,7 +272,7 @@ export class DocumentListComponent implements OnInit, OnDestroy, AfterViewInit {
   }
 
   clickMoreLike(documentID: number) {
-    this.list.quickFilter([
+    this.queryParamsService.loadFilterRules([
       { rule_type: FILTER_FULLTEXT_MORELIKE, value: documentID.toString() },
     ])
   }
index 4887f5e34dedee8b4140e9fbfbb862f4707628f1..c848fc6e5e3256ab00a0c8fa0a2f95f283423e8a 100644 (file)
@@ -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`,
       [
index 106194f36cfe2f66240d3364f67253415bff3c6f..d9f4b274ba19c88a5c6673cd0fd2100ed41d41f0 100644 (file)
@@ -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`,
       []
index 193ac8bb6c24a81620036218bbc6497d5582cd2b..3bfd1c5ff43320b5210671cd47595b14bab44797 100644 (file)
@@ -19,6 +19,7 @@ import {
   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 +43,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 +141,7 @@ export abstract class ManagementListComponent<T extends ObjectWithId>
   }
 
   filterDocuments(object: ObjectWithId) {
-    this.list.quickFilter([
+    this.queryParamsService.loadFilterRules([
       { rule_type: this.filterRuleType, value: object.id.toString() },
     ])
   }
index 01a1614bf7f66dbdc7a0da5dc3e182c976b77745..c1dd98e52c07b44e162d8b24d347ef3bece0c222 100644 (file)
@@ -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`,
       [
index b0d246a329b6e6f7d2b84600669e610141e8c88f..a822ce457bbceddbf525952d88352b89df181a70 100644 (file)
@@ -1,5 +1,5 @@
 import { Injectable } from '@angular/core'
-import { ActivatedRoute, Router } from '@angular/router'
+import { ActivatedRoute, Params, Router } from '@angular/router'
 import { Observable } from 'rxjs'
 import {
   cloneFilterRules,
@@ -9,6 +9,7 @@ import {
 import { PaperlessDocument } from '../data/paperless-document'
 import { PaperlessSavedView } from '../data/paperless-saved-view'
 import { DOCUMENT_LIST_SERVICE } from '../data/storage-keys'
+import { QueryParamsService } from './query-params.service'
 import { DocumentService, DOCUMENT_SORT_FIELDS } from './rest/document.service'
 import { SettingsService, SETTINGS_KEYS } from './settings.service'
 
@@ -220,6 +221,13 @@ export class DocumentListViewService {
     return this.activeListViewState.sortReverse
   }
 
+  get sortParams(): Params {
+    return {
+      sortField: this.sortField,
+      sortReverse: this.sortReverse,
+    }
+  }
+
   get collectionSize(): number {
     return this.activeListViewState.collectionSize
   }
@@ -265,14 +273,6 @@ export class DocumentListViewService {
     }
   }
 
-  quickFilter(filterRules: FilterRule[]) {
-    const params = this.documentService.filterRulesToQueryParams(filterRules)
-    this.router.navigate(['/documents'], {
-      relativeTo: this.route,
-      queryParams: params,
-    })
-  }
-
   getLastPage(): number {
     return Math.ceil(this.collectionSize / this.currentPageSize)
   }
@@ -435,8 +435,7 @@ export class DocumentListViewService {
   constructor(
     private documentService: DocumentService,
     private settings: SettingsService,
-    private router: Router,
-    private route: ActivatedRoute
+    private queryParamsService: QueryParamsService
   ) {
     let documentListViewConfigJson = localStorage.getItem(
       DOCUMENT_LIST_SERVICE.CURRENT_VIEW_CONFIG
diff --git a/src-ui/src/app/services/query-params.service.ts b/src-ui/src/app/services/query-params.service.ts
new file mode 100644 (file)
index 0000000..302d81b
--- /dev/null
@@ -0,0 +1,101 @@
+import { Injectable } from '@angular/core'
+import {
+  ActivatedRoute,
+  convertToParamMap,
+  ParamMap,
+  Params,
+  Router,
+} from '@angular/router'
+import { FilterRule } from '../data/filter-rule'
+import { FILTER_RULE_TYPES } from '../data/filter-rule-type'
+
+@Injectable({
+  providedIn: 'root',
+})
+export class QueryParamsService {
+  constructor(private router: Router, private route: ActivatedRoute) {}
+
+  private filterParams: Params
+  private _filterRules: FilterRule[]
+
+  set filterRules(filterRules: FilterRule[]) {
+    this._filterRules = filterRules
+    this.filterParams = this.filterRulesToQueryParams(filterRules)
+  }
+
+  get filterRules(): FilterRule[] {
+    return this._filterRules
+  }
+
+  set params(params: any) {
+    this.filterParams = params
+    this._filterRules = this.filterRulesFromQueryParams(
+      params.keys ? params : convertToParamMap(params) // ParamMap
+    )
+  }
+
+  get params(): Params {
+    return {
+      ...this.filterParams,
+    }
+  }
+
+  private filterRulesToQueryParams(filterRules: FilterRule[]): Object {
+    if (filterRules) {
+      let params = {}
+      for (let rule of filterRules) {
+        let ruleType = FILTER_RULE_TYPES.find((t) => t.id == rule.rule_type)
+        if (ruleType.multi) {
+          params[ruleType.filtervar] = params[ruleType.filtervar]
+            ? params[ruleType.filtervar] + ',' + rule.value
+            : rule.value
+        } else if (ruleType.isnull_filtervar && rule.value == null) {
+          params[ruleType.isnull_filtervar] = true
+        } else {
+          params[ruleType.filtervar] = rule.value
+        }
+      }
+      return params
+    } else {
+      return null
+    }
+  }
+
+  private filterRulesFromQueryParams(queryParams: ParamMap) {
+    const allFilterRuleQueryParams: string[] = FILTER_RULE_TYPES.map(
+      (rt) => rt.filtervar
+    )
+
+    // 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,
+            }
+          })
+        )
+      })
+
+    return filterRulesFromQueryParams
+  }
+
+  loadFilterRules(filterRules: FilterRule[]) {
+    this.filterRules = filterRules
+    this.router.navigate(['/documents'], {
+      relativeTo: this.route,
+      queryParams: this.params,
+    })
+  }
+}
index d06282bb80b5695de11417666733a251650aebcc..f9e68b850798c3c3c6c4ff8eb0c9ca24992dd643 100644 (file)
@@ -12,6 +12,7 @@ import { DocumentTypeService } from './document-type.service'
 import { TagService } from './tag.service'
 import { FILTER_RULE_TYPES } from 'src/app/data/filter-rule-type'
 import { PaperlessDocumentSuggestions } from 'src/app/data/paperless-document-suggestions'
+import { QueryParamsService } from '../query-params.service'
 
 export const DOCUMENT_SORT_FIELDS = [
   { field: 'archive_serial_number', name: $localize`ASN` },
@@ -52,32 +53,12 @@ export class DocumentService extends AbstractPaperlessService<PaperlessDocument>
     http: HttpClient,
     private correspondentService: CorrespondentService,
     private documentTypeService: DocumentTypeService,
-    private tagService: TagService
+    private tagService: TagService,
+    private queryParamsService: QueryParamsService
   ) {
     super(http, 'documents')
   }
 
-  public filterRulesToQueryParams(filterRules: FilterRule[]): Object {
-    if (filterRules) {
-      let params = {}
-      for (let rule of filterRules) {
-        let ruleType = FILTER_RULE_TYPES.find((t) => t.id == rule.rule_type)
-        if (ruleType.multi) {
-          params[ruleType.filtervar] = params[ruleType.filtervar]
-            ? params[ruleType.filtervar] + ',' + rule.value
-            : rule.value
-        } else if (ruleType.isnull_filtervar && rule.value == null) {
-          params[ruleType.isnull_filtervar] = true
-        } else {
-          params[ruleType.filtervar] = rule.value
-        }
-      }
-      return params
-    } else {
-      return null
-    }
-  }
-
   addObservablesToDocument(doc: PaperlessDocument) {
     if (doc.correspondent) {
       doc.correspondent$ = this.correspondentService.getCached(
@@ -101,12 +82,13 @@ export class DocumentService extends AbstractPaperlessService<PaperlessDocument>
     filterRules?: FilterRule[],
     extraParams = {}
   ): Observable<Results<PaperlessDocument>> {
+    this.queryParamsService.filterRules = filterRules
     return this.list(
       page,
       pageSize,
       sortField,
       sortReverse,
-      Object.assign(extraParams, this.filterRulesToQueryParams(filterRules))
+      Object.assign(extraParams, this.queryParamsService.params)
     ).pipe(
       map((results) => {
         results.results.forEach((doc) => this.addObservablesToDocument(doc))