mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-02 13:45:10 -05:00
filter by title or title+content fixes #636
This commit is contained in:
parent
e466c31bb3
commit
efa7b7b0b5
@ -1039,81 +1039,95 @@
|
|||||||
<context context-type="linenumber">106</context>
|
<context context-type="linenumber">106</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="5701618810648052610" datatype="html">
|
||||||
|
<source>Title</source>
|
||||||
|
<context-group purpose="location">
|
||||||
|
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
|
||||||
|
<context context-type="linenumber">73</context>
|
||||||
|
</context-group>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="3100631071441658964" datatype="html">
|
||||||
|
<source>Title & content</source>
|
||||||
|
<context-group purpose="location">
|
||||||
|
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
|
||||||
|
<context context-type="linenumber">74</context>
|
||||||
|
</context-group>
|
||||||
|
</trans-unit>
|
||||||
<trans-unit id="5195932016807797291" datatype="html">
|
<trans-unit id="5195932016807797291" datatype="html">
|
||||||
<source>Correspondent: <x id="PH" equiv-text="this.correspondents.find(c => c.id == +rule.value)?.name"/></source>
|
<source>Correspondent: <x id="PH" equiv-text="this.correspondents.find(c => c.id == +rule.value)?.name"/></source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
|
||||||
<context context-type="linenumber">29</context>
|
<context context-type="linenumber">32</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="8170755470576301659" datatype="html">
|
<trans-unit id="8170755470576301659" datatype="html">
|
||||||
<source>Without correspondent</source>
|
<source>Without correspondent</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
|
||||||
<context context-type="linenumber">31</context>
|
<context context-type="linenumber">34</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="8705701325879965907" datatype="html">
|
<trans-unit id="8705701325879965907" datatype="html">
|
||||||
<source>Type: <x id="PH" equiv-text="this.documentTypes.find(dt => dt.id == +rule.value)?.name"/></source>
|
<source>Type: <x id="PH" equiv-text="this.documentTypes.find(dt => dt.id == +rule.value)?.name"/></source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
|
||||||
<context context-type="linenumber">36</context>
|
<context context-type="linenumber">39</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4362173610367509215" datatype="html">
|
<trans-unit id="4362173610367509215" datatype="html">
|
||||||
<source>Without document type</source>
|
<source>Without document type</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
|
||||||
<context context-type="linenumber">38</context>
|
<context context-type="linenumber">41</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="8180755793012580465" datatype="html">
|
<trans-unit id="8180755793012580465" datatype="html">
|
||||||
<source>Tag: <x id="PH" equiv-text="this.tags.find(t => t.id == +rule.value)?.name"/></source>
|
<source>Tag: <x id="PH" equiv-text="this.tags.find(t => t.id == +rule.value)?.name"/></source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
|
||||||
<context context-type="linenumber">42</context>
|
<context context-type="linenumber">45</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="6494566478302448576" datatype="html">
|
<trans-unit id="6494566478302448576" datatype="html">
|
||||||
<source>Without any tag</source>
|
<source>Without any tag</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
|
||||||
<context context-type="linenumber">46</context>
|
<context context-type="linenumber">49</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="6523384805359286307" datatype="html">
|
<trans-unit id="6523384805359286307" datatype="html">
|
||||||
<source>Title: <x id="PH" equiv-text="rule.value"/></source>
|
<source>Title: <x id="PH" equiv-text="rule.value"/></source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
|
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.ts</context>
|
||||||
<context context-type="linenumber">50</context>
|
<context context-type="linenumber">53</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="02d184c288f567825a1fcbf83bcd3099a10853d5" datatype="html">
|
<trans-unit id="02d184c288f567825a1fcbf83bcd3099a10853d5" datatype="html">
|
||||||
<source>Filter tags</source>
|
<source>Filter tags</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.html</context>
|
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.html</context>
|
||||||
<context context-type="linenumber">12</context>
|
<context context-type="linenumber">20</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4b089ca12c472cf0b46167bb5afe4b527b301bbc" datatype="html">
|
<trans-unit id="4b089ca12c472cf0b46167bb5afe4b527b301bbc" datatype="html">
|
||||||
<source>Filter correspondents</source>
|
<source>Filter correspondents</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.html</context>
|
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.html</context>
|
||||||
<context context-type="linenumber">20</context>
|
<context context-type="linenumber">28</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="0ad509732aaf702b7ea8c771c7809fa84bc85908" datatype="html">
|
<trans-unit id="0ad509732aaf702b7ea8c771c7809fa84bc85908" datatype="html">
|
||||||
<source>Filter document types</source>
|
<source>Filter document types</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.html</context>
|
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.html</context>
|
||||||
<context context-type="linenumber">27</context>
|
<context context-type="linenumber">35</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="2d9d55f1b70142ff4597ba32179d16888fd9c6b2" datatype="html">
|
<trans-unit id="2d9d55f1b70142ff4597ba32179d16888fd9c6b2" datatype="html">
|
||||||
<source>Reset filters</source>
|
<source>Reset filters</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.html</context>
|
<context context-type="sourcefile">src/app/components/document-list/filter-editor/filter-editor.component.html</context>
|
||||||
<context context-type="linenumber">50</context>
|
<context context-type="linenumber">58</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="7593728289020204896" datatype="html">
|
<trans-unit id="7593728289020204896" datatype="html">
|
||||||
@ -1819,13 +1833,6 @@
|
|||||||
<context context-type="linenumber">18</context>
|
<context context-type="linenumber">18</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5701618810648052610" datatype="html">
|
|
||||||
<source>Title</source>
|
|
||||||
<context-group purpose="location">
|
|
||||||
<context context-type="sourcefile">src/app/services/rest/document.service.ts</context>
|
|
||||||
<context context-type="linenumber">19</context>
|
|
||||||
</context-group>
|
|
||||||
</trans-unit>
|
|
||||||
<trans-unit id="5066119607229701477" datatype="html">
|
<trans-unit id="5066119607229701477" datatype="html">
|
||||||
<source>Document type</source>
|
<source>Document type</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
|
@ -2,7 +2,15 @@
|
|||||||
<div class="col mb-2 mb-xl-0">
|
<div class="col mb-2 mb-xl-0">
|
||||||
<div class="form-inline d-flex align-items-center">
|
<div class="form-inline d-flex align-items-center">
|
||||||
<label class="text-muted mr-2 mb-0" i18n>Filter by:</label>
|
<label class="text-muted mr-2 mb-0" i18n>Filter by:</label>
|
||||||
<input class="form-control form-control-sm flex-fill w-auto" type="text" [(ngModel)]="titleFilter" placeholder="Title" i18n-placeholder>
|
<div class="input-group input-group-sm flex-fill w-auto">
|
||||||
|
<div class="input-group-prepend" ngbDropdown>
|
||||||
|
<button class="btn btn-outline-primary" ngbDropdownToggle>{{textFilterTargetName}}</button>
|
||||||
|
<div class="dropdown-menu shadow" ngbDropdownMenu>
|
||||||
|
<button *ngFor="let t of textFilterTargets" ngbDropdownItem [class.active]="textFilterTarget == t.id" (click)="changeTextFilterTarget(t.id)">{{t.name}}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<input class="form-control form-control-sm" type="text" [(ngModel)]="textFilter">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-100 d-xl-none"></div>
|
<div class="w-100 d-xl-none"></div>
|
||||||
|
@ -8,10 +8,13 @@ import { DocumentTypeService } from 'src/app/services/rest/document-type.service
|
|||||||
import { TagService } from 'src/app/services/rest/tag.service';
|
import { TagService } from 'src/app/services/rest/tag.service';
|
||||||
import { CorrespondentService } from 'src/app/services/rest/correspondent.service';
|
import { CorrespondentService } from 'src/app/services/rest/correspondent.service';
|
||||||
import { FilterRule } from 'src/app/data/filter-rule';
|
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_TAG, FILTER_TITLE, FILTER_TITLE_CONTENT } from 'src/app/data/filter-rule-type';
|
||||||
import { FilterableDropdownSelectionModel } from '../../common/filterable-dropdown/filterable-dropdown.component';
|
import { FilterableDropdownSelectionModel } from '../../common/filterable-dropdown/filterable-dropdown.component';
|
||||||
import { ToggleableItemState } from '../../common/filterable-dropdown/toggleable-dropdown-button/toggleable-dropdown-button.component';
|
import { ToggleableItemState } from '../../common/filterable-dropdown/toggleable-dropdown-button/toggleable-dropdown-button.component';
|
||||||
|
|
||||||
|
const TEXT_FILTER_TARGET_TITLE = "title"
|
||||||
|
const TEXT_FILTER_TARGET_TITLE_CONTENT = "title-content"
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-filter-editor',
|
selector: 'app-filter-editor',
|
||||||
templateUrl: './filter-editor.component.html',
|
templateUrl: './filter-editor.component.html',
|
||||||
@ -64,7 +67,19 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
|||||||
correspondents: PaperlessCorrespondent[] = []
|
correspondents: PaperlessCorrespondent[] = []
|
||||||
documentTypes: PaperlessDocumentType[] = []
|
documentTypes: PaperlessDocumentType[] = []
|
||||||
|
|
||||||
_titleFilter = ""
|
_textFilter = ""
|
||||||
|
|
||||||
|
textFilterTargets = [
|
||||||
|
{id: TEXT_FILTER_TARGET_TITLE, name: $localize`Title`},
|
||||||
|
{id: TEXT_FILTER_TARGET_TITLE_CONTENT, name: $localize`Title & content`}
|
||||||
|
]
|
||||||
|
|
||||||
|
textFilterTarget = TEXT_FILTER_TARGET_TITLE_CONTENT
|
||||||
|
|
||||||
|
get textFilterTargetName() {
|
||||||
|
return this.textFilterTargets.find(t => t.id == this.textFilterTarget)?.name
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
tagSelectionModel = new FilterableDropdownSelectionModel()
|
tagSelectionModel = new FilterableDropdownSelectionModel()
|
||||||
correspondentSelectionModel = new FilterableDropdownSelectionModel()
|
correspondentSelectionModel = new FilterableDropdownSelectionModel()
|
||||||
@ -80,7 +95,7 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
|||||||
this.documentTypeSelectionModel.clear(false)
|
this.documentTypeSelectionModel.clear(false)
|
||||||
this.tagSelectionModel.clear(false)
|
this.tagSelectionModel.clear(false)
|
||||||
this.correspondentSelectionModel.clear(false)
|
this.correspondentSelectionModel.clear(false)
|
||||||
this._titleFilter = null
|
this._textFilter = null
|
||||||
this.dateAddedBefore = null
|
this.dateAddedBefore = null
|
||||||
this.dateAddedAfter = null
|
this.dateAddedAfter = null
|
||||||
this.dateCreatedBefore = null
|
this.dateCreatedBefore = null
|
||||||
@ -89,7 +104,12 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
|||||||
value.forEach(rule => {
|
value.forEach(rule => {
|
||||||
switch (rule.rule_type) {
|
switch (rule.rule_type) {
|
||||||
case FILTER_TITLE:
|
case FILTER_TITLE:
|
||||||
this._titleFilter = rule.value
|
this._textFilter = rule.value
|
||||||
|
this.textFilterTarget = TEXT_FILTER_TARGET_TITLE
|
||||||
|
break
|
||||||
|
case FILTER_TITLE_CONTENT:
|
||||||
|
this._textFilter = rule.value
|
||||||
|
this.textFilterTarget = TEXT_FILTER_TARGET_TITLE_CONTENT
|
||||||
break
|
break
|
||||||
case FILTER_CREATED_AFTER:
|
case FILTER_CREATED_AFTER:
|
||||||
this.dateCreatedAfter = rule.value
|
this.dateCreatedAfter = rule.value
|
||||||
@ -121,8 +141,11 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
get filterRules(): FilterRule[] {
|
get filterRules(): FilterRule[] {
|
||||||
let filterRules: FilterRule[] = []
|
let filterRules: FilterRule[] = []
|
||||||
if (this._titleFilter) {
|
if (this._textFilter && this.textFilterTarget == TEXT_FILTER_TARGET_TITLE_CONTENT) {
|
||||||
filterRules.push({rule_type: FILTER_TITLE, value: this._titleFilter})
|
filterRules.push({rule_type: FILTER_TITLE_CONTENT, value: this._textFilter})
|
||||||
|
}
|
||||||
|
if (this._textFilter && this.textFilterTarget == TEXT_FILTER_TARGET_TITLE) {
|
||||||
|
filterRules.push({rule_type: FILTER_TITLE, value: this._textFilter})
|
||||||
}
|
}
|
||||||
if (this.tagSelectionModel.isNoneSelected()) {
|
if (this.tagSelectionModel.isNoneSelected()) {
|
||||||
filterRules.push({rule_type: FILTER_HAS_ANY_TAG, value: "false"})
|
filterRules.push({rule_type: FILTER_HAS_ANY_TAG, value: "false"})
|
||||||
@ -165,15 +188,15 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
|||||||
this.filterRulesChange.next(this.filterRules)
|
this.filterRulesChange.next(this.filterRules)
|
||||||
}
|
}
|
||||||
|
|
||||||
get titleFilter() {
|
get textFilter() {
|
||||||
return this._titleFilter
|
return this._textFilter
|
||||||
}
|
}
|
||||||
|
|
||||||
set titleFilter(value) {
|
set textFilter(value) {
|
||||||
this.titleFilterDebounce.next(value)
|
this.textFilterDebounce.next(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
titleFilterDebounce: Subject<string>
|
textFilterDebounce: Subject<string>
|
||||||
subscription: Subscription
|
subscription: Subscription
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
@ -181,19 +204,19 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
|||||||
this.correspondentService.listAll().subscribe(result => this.correspondents = result.results)
|
this.correspondentService.listAll().subscribe(result => this.correspondents = result.results)
|
||||||
this.documentTypeService.listAll().subscribe(result => this.documentTypes = result.results)
|
this.documentTypeService.listAll().subscribe(result => this.documentTypes = result.results)
|
||||||
|
|
||||||
this.titleFilterDebounce = new Subject<string>()
|
this.textFilterDebounce = new Subject<string>()
|
||||||
|
|
||||||
this.subscription = this.titleFilterDebounce.pipe(
|
this.subscription = this.textFilterDebounce.pipe(
|
||||||
debounceTime(400),
|
debounceTime(400),
|
||||||
distinctUntilChanged()
|
distinctUntilChanged()
|
||||||
).subscribe(title => {
|
).subscribe(text => {
|
||||||
this._titleFilter = title
|
this._textFilter = text
|
||||||
this.updateRules()
|
this.updateRules()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
this.titleFilterDebounce.complete()
|
this.textFilterDebounce.complete()
|
||||||
}
|
}
|
||||||
|
|
||||||
resetSelected() {
|
resetSelected() {
|
||||||
@ -223,4 +246,9 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
|||||||
onDocumentTypeDropdownOpen() {
|
onDocumentTypeDropdownOpen() {
|
||||||
this.documentTypeSelectionModel.apply()
|
this.documentTypeSelectionModel.apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
changeTextFilterTarget(target) {
|
||||||
|
this.textFilterTarget = target
|
||||||
|
this.updateRules()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,8 @@ export const FILTER_DOES_NOT_HAVE_TAG = 17
|
|||||||
|
|
||||||
export const FILTER_ASN_ISNULL = 18
|
export const FILTER_ASN_ISNULL = 18
|
||||||
|
|
||||||
|
export const FILTER_TITLE_CONTENT = 19
|
||||||
|
|
||||||
export const FILTER_RULE_TYPES: FilterRuleType[] = [
|
export const FILTER_RULE_TYPES: FilterRuleType[] = [
|
||||||
|
|
||||||
{id: FILTER_TITLE, filtervar: "title__icontains", datatype: "string", multi: false, default: ""},
|
{id: FILTER_TITLE, filtervar: "title__icontains", datatype: "string", multi: false, default: ""},
|
||||||
@ -47,7 +49,9 @@ export const FILTER_RULE_TYPES: FilterRuleType[] = [
|
|||||||
|
|
||||||
{id: FILTER_MODIFIED_BEFORE, filtervar: "modified__date__lt", datatype: "date", multi: false},
|
{id: FILTER_MODIFIED_BEFORE, filtervar: "modified__date__lt", datatype: "date", multi: false},
|
||||||
{id: FILTER_MODIFIED_AFTER, filtervar: "modified__date__gt", datatype: "date", multi: false},
|
{id: FILTER_MODIFIED_AFTER, filtervar: "modified__date__gt", datatype: "date", multi: false},
|
||||||
{id: FILTER_ASN_ISNULL, filtervar: "archive_serial_number__isnull", datatype: "boolean", multi: false}
|
{id: FILTER_ASN_ISNULL, filtervar: "archive_serial_number__isnull", datatype: "boolean", multi: false},
|
||||||
|
|
||||||
|
{id: FILTER_TITLE_CONTENT, filtervar: "title_content", datatype: "string", multi: false}
|
||||||
]
|
]
|
||||||
|
|
||||||
export interface FilterRuleType {
|
export interface FilterRuleType {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
from django.db.models import Q
|
||||||
from django_filters.rest_framework import BooleanFilter, FilterSet, Filter
|
from django_filters.rest_framework import BooleanFilter, FilterSet, Filter
|
||||||
|
|
||||||
from .models import Correspondent, Document, Tag, DocumentType, Log
|
from .models import Correspondent, Document, Tag, DocumentType, Log
|
||||||
@ -70,6 +71,16 @@ class InboxFilter(Filter):
|
|||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
|
||||||
|
class TitleContentFilter(Filter):
|
||||||
|
|
||||||
|
def filter(self, qs, value):
|
||||||
|
if value:
|
||||||
|
return qs.filter(Q(title__icontains=value) |
|
||||||
|
Q(content__icontains=value))
|
||||||
|
else:
|
||||||
|
return qs
|
||||||
|
|
||||||
|
|
||||||
class DocumentFilterSet(FilterSet):
|
class DocumentFilterSet(FilterSet):
|
||||||
|
|
||||||
is_tagged = BooleanFilter(
|
is_tagged = BooleanFilter(
|
||||||
@ -85,6 +96,8 @@ class DocumentFilterSet(FilterSet):
|
|||||||
|
|
||||||
is_in_inbox = InboxFilter()
|
is_in_inbox = InboxFilter()
|
||||||
|
|
||||||
|
title_content = TitleContentFilter()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Document
|
model = Document
|
||||||
fields = {
|
fields = {
|
||||||
|
18
src/documents/migrations/1014_auto_20210228_1614.py
Normal file
18
src/documents/migrations/1014_auto_20210228_1614.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.1.7 on 2021-02-28 15:14
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('documents', '1013_migrate_tag_colour'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='savedviewfilterrule',
|
||||||
|
name='rule_type',
|
||||||
|
field=models.PositiveIntegerField(choices=[(0, 'title contains'), (1, 'content contains'), (2, 'ASN is'), (3, 'correspondent is'), (4, 'document type is'), (5, 'is in inbox'), (6, 'has tag'), (7, 'has any tag'), (8, 'created before'), (9, 'created after'), (10, 'created year is'), (11, 'created month is'), (12, 'created day is'), (13, 'added before'), (14, 'added after'), (15, 'modified before'), (16, 'modified after'), (17, 'does not have tag'), (18, 'does not have ASN'), (19, 'title or content contains')], verbose_name='rule type'),
|
||||||
|
),
|
||||||
|
]
|
@ -385,6 +385,8 @@ class SavedViewFilterRule(models.Model):
|
|||||||
(15, _("modified before")),
|
(15, _("modified before")),
|
||||||
(16, _("modified after")),
|
(16, _("modified after")),
|
||||||
(17, _("does not have tag")),
|
(17, _("does not have tag")),
|
||||||
|
(18, _("does not have ASN")),
|
||||||
|
(19, _("title or content contains")),
|
||||||
]
|
]
|
||||||
|
|
||||||
saved_view = models.ForeignKey(
|
saved_view = models.ForeignKey(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user