From 9e46afafd7c6763d4d121e3e5c6fc68674b72e2b Mon Sep 17 00:00:00 2001 From: jonaswinkler Date: Mon, 7 Dec 2020 15:25:06 +0100 Subject: [PATCH] fixes #102 --- .../filter-editor/filter-editor.component.ts | 2 +- src-ui/src/app/data/filter-rule-type.ts | 12 ++++++++---- src/documents/filters.py | 12 +++++++++++- src/documents/tests/test_api.py | 18 ++++++++++++++++++ 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src-ui/src/app/components/filter-editor/filter-editor.component.ts b/src-ui/src/app/components/filter-editor/filter-editor.component.ts index 2eeac7dcd..b04127287 100644 --- a/src-ui/src/app/components/filter-editor/filter-editor.component.ts +++ b/src-ui/src/app/components/filter-editor/filter-editor.component.ts @@ -34,7 +34,7 @@ export class FilterEditorComponent implements OnInit { documentTypes: PaperlessDocumentType[] = [] newRuleClicked() { - this.filterRules.push({type: this.selectedRuleType, value: null}) + this.filterRules.push({type: this.selectedRuleType, value: this.selectedRuleType.default}) this.selectedRuleType = this.getRuleTypes().length > 0 ? this.getRuleTypes()[0] : null } diff --git a/src-ui/src/app/data/filter-rule-type.ts b/src-ui/src/app/data/filter-rule-type.ts index e1db34298..a35759f69 100644 --- a/src-ui/src/app/data/filter-rule-type.ts +++ b/src-ui/src/app/data/filter-rule-type.ts @@ -16,19 +16,22 @@ export const FILTER_ADDED_AFTER = 14 export const FILTER_MODIFIED_BEFORE = 15 export const FILTER_MODIFIED_AFTER = 16 +export const FILTER_DOES_NOT_HAVE_TAG = 17 + export const FILTER_RULE_TYPES: FilterRuleType[] = [ - {id: FILTER_TITLE, name: "Title contains", filtervar: "title__icontains", datatype: "string", multi: false}, - {id: FILTER_CONTENT, name: "Content contains", filtervar: "content__icontains", datatype: "string", multi: false}, + {id: FILTER_TITLE, name: "Title contains", filtervar: "title__icontains", datatype: "string", multi: false, default: ""}, + {id: FILTER_CONTENT, name: "Content contains", filtervar: "content__icontains", datatype: "string", multi: false, default: ""}, {id: FILTER_ASN, name: "ASN is", filtervar: "archive_serial_number", datatype: "number", multi: false}, {id: FILTER_CORRESPONDENT, name: "Correspondent is", filtervar: "correspondent__id", datatype: "correspondent", multi: false}, {id: FILTER_DOCUMENT_TYPE, name: "Document type is", filtervar: "document_type__id", datatype: "document_type", multi: false}, - {id: FILTER_IS_IN_INBOX, name: "Is in Inbox", filtervar: "is_in_inbox", datatype: "boolean", multi: false}, + {id: FILTER_IS_IN_INBOX, name: "Is in Inbox", filtervar: "is_in_inbox", datatype: "boolean", multi: false, default: true}, {id: FILTER_HAS_TAG, name: "Has tag", filtervar: "tags__id__all", datatype: "tag", multi: true}, - {id: FILTER_HAS_ANY_TAG, name: "Has any tag", filtervar: "is_tagged", datatype: "boolean", multi: false}, + {id: FILTER_DOES_NOT_HAVE_TAG, name: "Does not have tag", filtervar: "tags__id__none", datatype: "tag", multi: true}, + {id: FILTER_HAS_ANY_TAG, name: "Has any tag", filtervar: "is_tagged", datatype: "boolean", multi: false, default: true}, {id: FILTER_CREATED_BEFORE, name: "Created before", filtervar: "created__date__lt", datatype: "date", multi: false}, {id: FILTER_CREATED_AFTER, name: "Created after", filtervar: "created__date__gt", datatype: "date", multi: false}, @@ -50,4 +53,5 @@ export interface FilterRuleType { filtervar: string datatype: string //number, string, boolean, date multi: boolean + default?: any } \ No newline at end of file diff --git a/src/documents/filters.py b/src/documents/filters.py index 770e0e5af..64ef826ce 100755 --- a/src/documents/filters.py +++ b/src/documents/filters.py @@ -37,6 +37,10 @@ class DocumentTypeFilterSet(FilterSet): class TagsFilter(Filter): + def __init__(self, exclude=False): + super(TagsFilter, self).__init__() + self.exclude = exclude + def filter(self, qs, value): if not value: return qs @@ -47,7 +51,11 @@ class TagsFilter(Filter): return qs for tag_id in tag_ids: - qs = qs.filter(tags__id=tag_id) + print(self.exclude, tag_id) + if self.exclude: + qs = qs.exclude(tags__id=tag_id) + else: + qs = qs.filter(tags__id=tag_id) return qs @@ -74,6 +82,8 @@ class DocumentFilterSet(FilterSet): tags__id__all = TagsFilter() + tags__id__none = TagsFilter(exclude=True) + is_in_inbox = InboxFilter() class Meta: diff --git a/src/documents/tests/test_api.py b/src/documents/tests/test_api.py index b900ee653..986094db6 100644 --- a/src/documents/tests/test_api.py +++ b/src/documents/tests/test_api.py @@ -195,6 +195,24 @@ class TestDocumentApi(DirectoriesMixin, APITestCase): results = response.data['results'] self.assertEqual(len(results), 3) + response = self.client.get("/api/documents/?tags__id__none={}".format(tag_3.id)) + self.assertEqual(response.status_code, 200) + results = response.data['results'] + self.assertEqual(len(results), 2) + self.assertEqual(results[0]['id'], doc1.id) + self.assertEqual(results[1]['id'], doc2.id) + + response = self.client.get("/api/documents/?tags__id__none={},{}".format(tag_3.id, tag_2.id)) + self.assertEqual(response.status_code, 200) + results = response.data['results'] + self.assertEqual(len(results), 1) + self.assertEqual(results[0]['id'], doc1.id) + + response = self.client.get("/api/documents/?tags__id__none={},{}".format(tag_2.id, tag_inbox.id)) + self.assertEqual(response.status_code, 200) + results = response.data['results'] + self.assertEqual(len(results), 0) + def test_search_no_query(self): response = self.client.get("/api/search/") results = response.data['results']