mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-07-28 18:24:38 -05:00
Add support for 'any' ('OR') of tags when filtering
This commit is contained in:
@@ -12,6 +12,16 @@
|
||||
</button>
|
||||
<div class="dropdown-menu py-0 shadow" ngbDropdownMenu attr.aria-labelledby="dropdown{{title}}">
|
||||
<div class="list-group list-group-flush">
|
||||
<div *ngIf="!editing && multiple" class="list-group-item d-flex">
|
||||
<div class="btn-group btn-group-xs btn-group-toggle flex-fill" ngbRadioGroup [(ngModel)]="selectionModel.logicalOperator">
|
||||
<label ngbButtonLabel class="btn btn-outline-primary">
|
||||
<input ngbButton type="radio" name="logicalOperator" value="and"> All
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn btn-outline-primary">
|
||||
<input ngbButton type="radio" name="logicalOperator" value="or"> Any
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-group-item">
|
||||
<div class="input-group input-group-sm">
|
||||
<input class="form-control" type="text" [(ngModel)]="filterText" [placeholder]="filterPlaceholder" (keyup.enter)="listFilterEnter()" #listFilterTextInput>
|
||||
|
@@ -12,3 +12,22 @@
|
||||
overflow-y: scroll;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-group-xs {
|
||||
> .btn {
|
||||
padding: 0.2rem 0.25rem;
|
||||
font-size: 0.675rem;
|
||||
line-height: 1.2;
|
||||
border-radius: 0.15rem;
|
||||
}
|
||||
|
||||
> .btn:not(:first-child) {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
> .btn:not(:last-child) {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
}
|
||||
|
@@ -15,6 +15,7 @@ export class FilterableDropdownSelectionModel {
|
||||
changed = new Subject<FilterableDropdownSelectionModel>()
|
||||
|
||||
multiple = false
|
||||
logicalOperator = 'and'
|
||||
|
||||
items: MatchingModel[] = []
|
||||
|
||||
@@ -83,7 +84,7 @@ export class FilterableDropdownSelectionModel {
|
||||
if (fireEvent) {
|
||||
this.changed.next(this)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private getNonTemporary(id: number) {
|
||||
|
@@ -8,7 +8,7 @@ import { DocumentTypeService } from 'src/app/services/rest/document-type.service
|
||||
import { TagService } from 'src/app/services/rest/tag.service';
|
||||
import { CorrespondentService } from 'src/app/services/rest/correspondent.service';
|
||||
import { FilterRule } from 'src/app/data/filter-rule';
|
||||
import { FILTER_ADDED_AFTER, FILTER_ADDED_BEFORE, FILTER_CORRESPONDENT, FILTER_CREATED_AFTER, FILTER_CREATED_BEFORE, FILTER_DOCUMENT_TYPE, FILTER_HAS_ANY_TAG, FILTER_HAS_TAG, FILTER_TITLE } from 'src/app/data/filter-rule-type';
|
||||
import { FILTER_ADDED_AFTER, FILTER_ADDED_BEFORE, FILTER_CORRESPONDENT, FILTER_CREATED_AFTER, FILTER_CREATED_BEFORE, FILTER_DOCUMENT_TYPE, FILTER_HAS_ANY_TAG, FILTER_HAS_TAGS_ALL, FILTER_HAS_TAGS_ANY, FILTER_TITLE } from 'src/app/data/filter-rule-type';
|
||||
import { FilterableDropdownSelectionModel } from '../../common/filterable-dropdown/filterable-dropdown.component';
|
||||
import { ToggleableItemState } from '../../common/filterable-dropdown/toggleable-dropdown-button/toggleable-dropdown-button.component';
|
||||
|
||||
@@ -38,7 +38,7 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
||||
return $localize`Without document type`
|
||||
}
|
||||
|
||||
case FILTER_HAS_TAG:
|
||||
case FILTER_HAS_TAGS_ALL:
|
||||
return $localize`Tag: ${this.tags.find(t => t.id == +rule.value)?.name}`
|
||||
|
||||
case FILTER_HAS_ANY_TAG:
|
||||
@@ -101,7 +101,11 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
||||
case FILTER_ADDED_BEFORE:
|
||||
this.dateAddedBefore = rule.value
|
||||
break
|
||||
case FILTER_HAS_TAG:
|
||||
case FILTER_HAS_TAGS_ALL:
|
||||
this.tagSelectionModel.set(rule.value ? +rule.value : null, ToggleableItemState.Selected, false)
|
||||
break
|
||||
case FILTER_HAS_TAGS_ANY:
|
||||
this.tagSelectionModel.logicalOperator = 'or'
|
||||
this.tagSelectionModel.set(rule.value ? +rule.value : null, ToggleableItemState.Selected, false)
|
||||
break
|
||||
case FILTER_HAS_ANY_TAG:
|
||||
@@ -125,8 +129,9 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
||||
if (this.tagSelectionModel.isNoneSelected()) {
|
||||
filterRules.push({rule_type: FILTER_HAS_ANY_TAG, value: "false"})
|
||||
} else {
|
||||
const tagFilterType = this.tagSelectionModel.logicalOperator == 'and' ? FILTER_HAS_TAGS_ALL : FILTER_HAS_TAGS_ANY
|
||||
this.tagSelectionModel.getSelectedItems().filter(tag => tag.id).forEach(tag => {
|
||||
filterRules.push({rule_type: FILTER_HAS_TAG, value: tag.id?.toString()})
|
||||
filterRules.push({rule_type: tagFilterType, value: tag.id?.toString()})
|
||||
})
|
||||
}
|
||||
this.correspondentSelectionModel.getSelectedItems().forEach(correspondent => {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { FILTER_HAS_TAG } from 'src/app/data/filter-rule-type';
|
||||
import { FILTER_HAS_TAGS_ALL } from 'src/app/data/filter-rule-type';
|
||||
import { TAG_COLOURS, PaperlessTag } from 'src/app/data/paperless-tag';
|
||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service';
|
||||
import { TagService } from 'src/app/services/rest/tag.service';
|
||||
@@ -31,7 +31,7 @@ export class TagListComponent extends GenericListComponent<PaperlessTag> {
|
||||
}
|
||||
|
||||
filterDocuments(object: PaperlessTag) {
|
||||
this.list.quickFilter([{rule_type: FILTER_HAS_TAG, value: object.id.toString()}])
|
||||
this.list.quickFilter([{rule_type: FILTER_HAS_TAGS_ALL, value: object.id.toString()}])
|
||||
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user