mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-07-28 18:24:38 -05:00
Merge pull request #1868 from paperless-ngx/fix/issue-1866
Fix: independent control of saved views
This commit is contained in:
@@ -16,4 +16,7 @@
|
||||
<ngb-progressbar *ngIf="!confirmButtonEnabled" style="height: 1px;" type="dark" [max]="secondsTotal" [value]="seconds"></ngb-progressbar>
|
||||
<span class="visually-hidden">{{ seconds | number: '1.0-0' }} seconds</span>
|
||||
</button>
|
||||
<button *ngIf="alternativeBtnCaption" type="button" class="btn" [class]="alternativeBtnClass" (click)="alternative()" [disabled]="!alternativeButtonEnabled || !buttonsEnabled">
|
||||
{{alternativeBtnCaption}}
|
||||
</button>
|
||||
</div>
|
||||
|
@@ -13,6 +13,9 @@ export class ConfirmDialogComponent {
|
||||
@Output()
|
||||
public confirmClicked = new EventEmitter()
|
||||
|
||||
@Output()
|
||||
public alternativeClicked = new EventEmitter()
|
||||
|
||||
@Input()
|
||||
title = $localize`Confirmation`
|
||||
|
||||
@@ -28,14 +31,22 @@ export class ConfirmDialogComponent {
|
||||
@Input()
|
||||
btnCaption = $localize`Confirm`
|
||||
|
||||
@Input()
|
||||
alternativeBtnClass = 'btn-secondary'
|
||||
|
||||
@Input()
|
||||
alternativeBtnCaption
|
||||
|
||||
@Input()
|
||||
buttonsEnabled = true
|
||||
|
||||
confirmButtonEnabled = true
|
||||
alternativeButtonEnabled = true
|
||||
seconds = 0
|
||||
secondsTotal = 0
|
||||
|
||||
confirmSubject: Subject<boolean>
|
||||
alternativeSubject: Subject<boolean>
|
||||
|
||||
delayConfirm(seconds: number) {
|
||||
const refreshInterval = 0.15 // s
|
||||
@@ -68,4 +79,10 @@ export class ConfirmDialogComponent {
|
||||
this.confirmSubject?.next(true)
|
||||
this.confirmSubject?.complete()
|
||||
}
|
||||
|
||||
alternative() {
|
||||
this.alternativeClicked.emit()
|
||||
this.alternativeSubject?.next(true)
|
||||
this.alternativeSubject?.complete()
|
||||
}
|
||||
}
|
||||
|
@@ -60,14 +60,19 @@
|
||||
</div>
|
||||
|
||||
<div class="btn-group ms-2 flex-fill" ngbDropdown role="group">
|
||||
<button class="btn btn-sm btn-outline-primary dropdown-toggle flex-fill" tourAnchor="tour.documents-views" ngbDropdownToggle i18n>Views</button>
|
||||
<button class="btn btn-sm btn-outline-primary dropdown-toggle flex-fill" tourAnchor="tour.documents-views" ngbDropdownToggle>
|
||||
<ng-container i18n>Views</ng-container>
|
||||
<div *ngIf="savedViewIsModified" class="position-absolute top-0 start-100 p-2 translate-middle badge bg-secondary border border-light rounded-circle">
|
||||
<span class="visually-hidden">selected</span>
|
||||
</div>
|
||||
</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.id)">{{view.name}}</button>
|
||||
<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>
|
||||
|
@@ -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()
|
||||
})
|
||||
|
Reference in New Issue
Block a user