mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-10-30 03:56:23 -05:00 
			
		
		
		
	Merge pull request #270 from shamoon/fix/issue-267
Allow 'reset' filters on saved views
This commit is contained in:
		| @@ -5,7 +5,7 @@ | ||||
|       <svg class="toolbaricon" fill="currentColor"> | ||||
|         <use xlink:href="assets/bootstrap-icons.svg#text-indent-left" /> | ||||
|       </svg> <ng-container i18n>Select</ng-container> | ||||
|        | ||||
|  | ||||
|     </button> | ||||
|     <div ngbDropdownMenu aria-labelledby="dropdownSelect" class="shadow"> | ||||
|       <button ngbDropdownItem (click)="list.selectNone()" i18n>Select none</button> | ||||
| @@ -78,7 +78,7 @@ | ||||
| </app-page-header> | ||||
|  | ||||
| <div class="w-100 mb-2 mb-sm-4"> | ||||
|   <app-filter-editor [hidden]="isBulkEditing" [(filterRules)]="list.filterRules" #filterEditor></app-filter-editor> | ||||
|   <app-filter-editor [hidden]="isBulkEditing" [(filterRules)]="list.filterRules" [rulesModified]="filterRulesModified" (filterRulesChange)="rulesChanged()" (reset)="resetFilters()" #filterEditor></app-filter-editor> | ||||
|   <app-bulk-editor [hidden]="!isBulkEditing"></app-bulk-editor> | ||||
| </div> | ||||
|  | ||||
|   | ||||
| @@ -30,9 +30,11 @@ export class DocumentListComponent implements OnInit { | ||||
|   private filterEditor: FilterEditorComponent | ||||
|  | ||||
|   @ViewChildren(SortableDirective) headers: QueryList<SortableDirective>; | ||||
|    | ||||
|  | ||||
|   displayMode = 'smallCards' // largeCards, smallCards, details | ||||
|  | ||||
|   filterRulesModified: boolean = false | ||||
|  | ||||
|   get isFiltered() { | ||||
|     return this.list.filterRules?.length > 0 | ||||
|   } | ||||
| @@ -69,18 +71,20 @@ export class DocumentListComponent implements OnInit { | ||||
|             this.router.navigate(["404"]) | ||||
|             return | ||||
|           } | ||||
|  | ||||
|           this.list.savedView = view | ||||
|           this.list.reload() | ||||
|           this.rulesChanged() | ||||
|         }) | ||||
|       } else { | ||||
|         this.list.savedView = null | ||||
|         this.list.reload() | ||||
|         this.rulesChanged() | ||||
|       } | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   loadViewConfig(view: PaperlessSavedView) { | ||||
|     this.filterRulesModified = false | ||||
|     this.list.load(view) | ||||
|     this.list.reload() | ||||
|   } | ||||
| @@ -105,6 +109,7 @@ export class DocumentListComponent implements OnInit { | ||||
|         sort_reverse: this.list.sortReverse, | ||||
|         sort_field: this.list.sortField | ||||
|       } | ||||
|  | ||||
|       this.savedViewService.create(savedView).subscribe(() => { | ||||
|         modal.close() | ||||
|         this.toastService.showInfo($localize`View "${savedView.name}" created successfully.`) | ||||
| @@ -115,6 +120,46 @@ export class DocumentListComponent implements OnInit { | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   resetFilters(): void { | ||||
|     this.filterRulesModified = false | ||||
|     if (this.list.savedViewId) { | ||||
|       this.savedViewService.getCached(this.list.savedViewId).subscribe(viewUntouched => { | ||||
|         this.list.filterRules = viewUntouched.filter_rules | ||||
|         this.list.reload() | ||||
|       }) | ||||
|     } else { | ||||
|       this.list.filterRules = [] | ||||
|       this.list.reload() | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   rulesChanged() { | ||||
|     let modified = false | ||||
|     if (this.list.savedView == null) { | ||||
|       modified = this.list.filterRules.length > 0 // documents list is modified if it has any filters | ||||
|     } else { | ||||
|       // compare savedView current filters vs original | ||||
|       this.savedViewService.getCached(this.list.savedViewId).subscribe(view => { | ||||
|         let filterRulesInitial = view.filter_rules | ||||
|  | ||||
|         if (this.list.filterRules.length !== filterRulesInitial.length) modified = true | ||||
|         else { | ||||
|           modified = this.list.filterRules.some(rule => { | ||||
|             return (filterRulesInitial.find(fri => fri.rule_type == rule.rule_type && fri.value == rule.value) == undefined) | ||||
|           }) | ||||
|  | ||||
|           if (!modified) { | ||||
|             // only check other direction if we havent already determined is modified | ||||
|             modified = filterRulesInitial.some(rule => { | ||||
|               this.list.filterRules.find(fr => fr.rule_type == rule.rule_type && fr.value == rule.value) == undefined | ||||
|             }) | ||||
|           } | ||||
|         } | ||||
|       }) | ||||
|     } | ||||
|     this.filterRulesModified = modified | ||||
|   } | ||||
|  | ||||
|   clickTag(tagID: number) { | ||||
|     this.list.selectNone() | ||||
|     setTimeout(() => { | ||||
|   | ||||
| @@ -41,11 +41,11 @@ | ||||
|    </div> | ||||
|    <div class="w-100 d-xl-none"></div> | ||||
|    <div class="col col-xl-auto mb-2 mb-xl-0"> | ||||
|      <button class="btn btn-link btn-sm px-0 mx-0 ml-xl-n4" [disabled]="!hasFilters()" (click)="clearSelected()"> | ||||
|      <button class="btn btn-link btn-sm px-0 mx-0 ml-xl-n4" [disabled]="!rulesModified" (click)="resetSelected()"> | ||||
|        <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-x" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | ||||
|          <path fill-rule="evenodd" d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"/> | ||||
|        </svg> <ng-container i18n>Clear all filters</ng-container> | ||||
|         | ||||
|        </svg> <ng-container i18n>Reset filters</ng-container> | ||||
|  | ||||
|      </button> | ||||
|    </div> | ||||
| </div> | ||||
|   | ||||
| @@ -40,7 +40,7 @@ export class FilterEditorComponent implements OnInit, OnDestroy { | ||||
|  | ||||
|         case FILTER_HAS_TAG: | ||||
|           return $localize`Tag: ${this.tags.find(t => t.id == +rule.value)?.name}` | ||||
|          | ||||
|  | ||||
|         case FILTER_HAS_ANY_TAG: | ||||
|           if (rule.value == "false") { | ||||
|             return $localize`Without any tag` | ||||
| @@ -127,7 +127,7 @@ export class FilterEditorComponent implements OnInit, OnDestroy { | ||||
|     } else { | ||||
|       this.tagSelectionModel.getSelectedItems().filter(tag => tag.id).forEach(tag => { | ||||
|         filterRules.push({rule_type: FILTER_HAS_TAG, value: tag.id?.toString()}) | ||||
|       })   | ||||
|       }) | ||||
|     } | ||||
|     this.correspondentSelectionModel.getSelectedItems().forEach(correspondent => { | ||||
|       filterRules.push({rule_type: FILTER_CORRESPONDENT, value: correspondent.id?.toString()}) | ||||
| @@ -153,16 +153,16 @@ export class FilterEditorComponent implements OnInit, OnDestroy { | ||||
|   @Output() | ||||
|   filterRulesChange = new EventEmitter<FilterRule[]>() | ||||
|  | ||||
|   @Output() | ||||
|   reset = new EventEmitter() | ||||
|  | ||||
|   @Input() | ||||
|   rulesModified: boolean = false | ||||
|  | ||||
|   updateRules() { | ||||
|     this.filterRulesChange.next(this.filterRules) | ||||
|   } | ||||
|  | ||||
|   hasFilters() { | ||||
|     return this._titleFilter ||  | ||||
|       this.dateAddedAfter || this.dateAddedBefore || this.dateCreatedAfter || this.dateCreatedBefore || | ||||
|       this.tagSelectionModel.selectionSize() || this.correspondentSelectionModel.selectionSize() || this.documentTypeSelectionModel.selectionSize() | ||||
|   } | ||||
|  | ||||
|   get titleFilter() { | ||||
|     return this._titleFilter | ||||
|   } | ||||
| @@ -194,16 +194,8 @@ export class FilterEditorComponent implements OnInit, OnDestroy { | ||||
|     this.titleFilterDebounce.complete() | ||||
|   } | ||||
|  | ||||
|   clearSelected() { | ||||
|     this._titleFilter = "" | ||||
|     this.tagSelectionModel.clear(false) | ||||
|     this.documentTypeSelectionModel.clear(false) | ||||
|     this.correspondentSelectionModel.clear(false) | ||||
|     this.dateAddedBefore = null | ||||
|     this.dateAddedAfter = null | ||||
|     this.dateCreatedBefore = null | ||||
|     this.dateCreatedAfter = null | ||||
|     this.updateRules() | ||||
|   resetSelected() { | ||||
|     this.reset.next() | ||||
|   } | ||||
|  | ||||
|   toggleTag(tagId: number) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Jonas Winkler
					Jonas Winkler