]> git.ipfire.org Git - thirdparty/paperless-ngx.git/commitdiff
Allow independent saved view control
authorMichael Shamoon <4887959+shamoon@users.noreply.github.com>
Wed, 26 Oct 2022 19:48:22 +0000 (12:48 -0700)
committerMichael Shamoon <4887959+shamoon@users.noreply.github.com>
Wed, 26 Oct 2022 19:54:44 +0000 (12:54 -0700)
src-ui/src/app/components/document-list/document-list.component.html
src-ui/src/app/components/document-list/document-list.component.ts
src-ui/src/app/services/document-list-view.service.ts
src-ui/src/styles.scss

index ca725b175f7c2b59aeeb6dbcd73f458364db7538..5cec94919a857198067ba9f68b75cad36e460b96 100644 (file)
@@ -67,7 +67,7 @@
         <div class="dropdown-divider" *ngIf="savedViewService.allViews.length > 0"></div>
       </ng-container>
 
-      <button ngbDropdownItem (click)="saveViewConfig()" *ngIf="list.activeSavedViewId" i18n>Save "{{list.activeSavedViewTitle}}"</button>
+      <button ngbDropdownItem (click)="saveViewConfig()" *ngIf="list.activeSavedViewId" [disabled]="!savedViewIsModified" i18n>Save "{{list.activeSavedViewTitle}}"</button>
       <button ngbDropdownItem (click)="saveViewConfigAs()" i18n>Save as...</button>
     </div>
   </div>
index a0c6899f8d01314a64a62003b4a85dd065daea99..3c1e6775f9c4382aacbb665b04e286d96f078368 100644 (file)
@@ -9,7 +9,11 @@ import {
 import { ActivatedRoute, convertToParamMap, Router } from '@angular/router'
 import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
 import { filter, first, map, Subject, switchMap, takeUntil } from 'rxjs'
-import { FilterRule, isFullTextFilterRule } from 'src/app/data/filter-rule'
+import {
+  FilterRule,
+  filterRulesDiffer,
+  isFullTextFilterRule,
+} from 'src/app/data/filter-rule'
 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'
@@ -54,15 +58,36 @@ export class DocumentListComponent implements OnInit, OnDestroy {
   displayMode = 'smallCards' // largeCards, smallCards, details
 
   unmodifiedFilterRules: FilterRule[] = []
+  private unmodifiedSavedView: PaperlessSavedView
 
   private unsubscribeNotifier: Subject<any> = new Subject()
 
+  get savedViewIsModified(): boolean {
+    if (!this.list.activeSavedViewId || !this.unmodifiedSavedView) return false
+    else {
+      return (
+        this.unmodifiedSavedView.sort_field !== this.list.sortField ||
+        this.unmodifiedSavedView.sort_reverse !== this.list.sortReverse ||
+        filterRulesDiffer(
+          this.unmodifiedSavedView.filter_rules,
+          this.list.filterRules
+        )
+      )
+    }
+  }
+
   get isFiltered() {
     return this.list.filterRules?.length > 0
   }
 
   getTitle() {
-    return this.list.activeSavedViewTitle || $localize`Documents`
+    let title = this.list.activeSavedViewTitle
+    if (title && this.savedViewIsModified) {
+      title += '*'
+    } else if (!title) {
+      title = $localize`Documents`
+    }
+    return title
   }
 
   getSortFields() {
@@ -122,7 +147,7 @@ export class DocumentListComponent implements OnInit, OnDestroy {
           this.router.navigate(['404'])
           return
         }
-
+        this.unmodifiedSavedView = view
         this.list.activateSavedViewWithQueryParams(
           view,
           convertToParamMap(this.route.snapshot.queryParams)
@@ -165,7 +190,8 @@ export class DocumentListComponent implements OnInit, OnDestroy {
       this.savedViewService
         .patch(savedView)
         .pipe(first())
-        .subscribe((result) => {
+        .subscribe((view) => {
+          this.unmodifiedSavedView = view
           this.toastService.showInfo(
             $localize`View "${this.list.activeSavedViewTitle}" saved successfully.`
           )
@@ -179,6 +205,7 @@ export class DocumentListComponent implements OnInit, OnDestroy {
       .getCached(viewID)
       .pipe(first())
       .subscribe((view) => {
+        this.unmodifiedSavedView = view
         this.list.activateSavedView(view)
         this.list.reload()
       })
index 5f0c7a237efe516b9c3b7862a81f7915ba7eb9be..3eb036710b6550c41c316ecbf49e8244e6747a17 100644 (file)
@@ -225,10 +225,7 @@ export class DocumentListViewService {
             let base = ['/documents']
             this.router.navigate(base, {
               queryParams: paramsFromViewState(activeListViewState),
-              replaceUrl: !(
-                this.router.routerState.snapshot.url.includes('?') ||
-                this.router.routerState.snapshot.url.includes('/view/')
-              ), // in case navigating from params-less /documents or /view
+              replaceUrl: !this.router.routerState.snapshot.url.includes('?'), // in case navigating from params-less /documents
             })
           } else if (this._activeSavedViewId) {
             this.router.navigate([], {
@@ -279,7 +276,6 @@ export class DocumentListViewService {
     ) {
       this.activeListViewState.sortField = 'created'
     }
-    this._activeSavedViewId = null
     this.activeListViewState.filterRules = filterRules
     this.reload()
     this.reduceSelectionToFilter()
@@ -293,7 +289,6 @@ export class DocumentListViewService {
   set sortField(field: string) {
     this.activeListViewState.sortField = field
     this.reload()
-    this._activeSavedViewId = null
     this.saveDocumentListView()
   }
 
@@ -304,7 +299,6 @@ export class DocumentListViewService {
   set sortReverse(reverse: boolean) {
     this.activeListViewState.sortReverse = reverse
     this.reload()
-    this._activeSavedViewId = null
     this.saveDocumentListView()
   }
 
index f096e7a33dd5ad81903766148db5f2eef87ff8b6..27b495d8f39a9e6effd49e254857ffe3d355959f 100644 (file)
@@ -393,6 +393,10 @@ textarea,
       background-color: var(--bs-primary);
       color: var(--pngx-primary-text-contrast);
     }
+
+    &.disabled, &:disabled {
+      opacity: 50%;
+    }
   }
 }