mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-09 09:58:20 -05:00
Feature: filter by mime type
This commit is contained in:
parent
880f08599a
commit
bb026c64c4
@ -60,6 +60,7 @@ import {
|
|||||||
FILTER_HAS_STORAGE_PATH_ANY,
|
FILTER_HAS_STORAGE_PATH_ANY,
|
||||||
FILTER_HAS_TAGS_ALL,
|
FILTER_HAS_TAGS_ALL,
|
||||||
FILTER_HAS_TAGS_ANY,
|
FILTER_HAS_TAGS_ANY,
|
||||||
|
FILTER_MIME_TYPE,
|
||||||
FILTER_OWNER,
|
FILTER_OWNER,
|
||||||
FILTER_OWNER_ANY,
|
FILTER_OWNER_ANY,
|
||||||
FILTER_OWNER_DOES_NOT_INCLUDE,
|
FILTER_OWNER_DOES_NOT_INCLUDE,
|
||||||
@ -389,6 +390,18 @@ describe('FilterEditorComponent', () => {
|
|||||||
expect(component.textFilterModifier).toEqual('less') // TEXT_FILTER_MODIFIER_LT
|
expect(component.textFilterModifier).toEqual('less') // TEXT_FILTER_MODIFIER_LT
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
it('should ingest text filter rules for mime type', fakeAsync(() => {
|
||||||
|
expect(component.textFilter).toEqual(null)
|
||||||
|
component.filterRules = [
|
||||||
|
{
|
||||||
|
rule_type: FILTER_MIME_TYPE,
|
||||||
|
value: 'pdf',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
expect(component.textFilter).toEqual('pdf')
|
||||||
|
expect(component.textFilterTarget).toEqual('mime-type') // TEXT_FILTER_TARGET_MIME_TYPE
|
||||||
|
}))
|
||||||
|
|
||||||
it('should ingest text filter rules for fulltext query', fakeAsync(() => {
|
it('should ingest text filter rules for fulltext query', fakeAsync(() => {
|
||||||
expect(component.textFilter).toEqual(null)
|
expect(component.textFilter).toEqual(null)
|
||||||
component.filterRules = [
|
component.filterRules = [
|
||||||
@ -1222,6 +1235,24 @@ describe('FilterEditorComponent', () => {
|
|||||||
])
|
])
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
it('should convert user input to correct filter rules on mime type', fakeAsync(() => {
|
||||||
|
component.textFilterInput.nativeElement.value = 'pdf'
|
||||||
|
component.textFilterInput.nativeElement.dispatchEvent(new Event('input'))
|
||||||
|
const textFieldTargetDropdown = fixture.debugElement.queryAll(
|
||||||
|
By.directive(NgbDropdownItem)
|
||||||
|
)[5]
|
||||||
|
textFieldTargetDropdown.triggerEventHandler('click') // TEXT_FILTER_TARGET_MIME_TYPE
|
||||||
|
fixture.detectChanges()
|
||||||
|
tick(400)
|
||||||
|
expect(component.textFilterTarget).toEqual('mime-type')
|
||||||
|
expect(component.filterRules).toEqual([
|
||||||
|
{
|
||||||
|
rule_type: FILTER_MIME_TYPE,
|
||||||
|
value: 'pdf',
|
||||||
|
},
|
||||||
|
])
|
||||||
|
}))
|
||||||
|
|
||||||
it('should convert user input to correct filter rules on full text query', fakeAsync(() => {
|
it('should convert user input to correct filter rules on full text query', fakeAsync(() => {
|
||||||
component.textFilterInput.nativeElement.value = 'foo'
|
component.textFilterInput.nativeElement.value = 'foo'
|
||||||
component.textFilterInput.nativeElement.dispatchEvent(new Event('input'))
|
component.textFilterInput.nativeElement.dispatchEvent(new Event('input'))
|
||||||
|
@ -66,6 +66,7 @@ import {
|
|||||||
FILTER_HAS_STORAGE_PATH_ANY,
|
FILTER_HAS_STORAGE_PATH_ANY,
|
||||||
FILTER_HAS_TAGS_ALL,
|
FILTER_HAS_TAGS_ALL,
|
||||||
FILTER_HAS_TAGS_ANY,
|
FILTER_HAS_TAGS_ANY,
|
||||||
|
FILTER_MIME_TYPE,
|
||||||
FILTER_OWNER,
|
FILTER_OWNER,
|
||||||
FILTER_OWNER_ANY,
|
FILTER_OWNER_ANY,
|
||||||
FILTER_OWNER_DOES_NOT_INCLUDE,
|
FILTER_OWNER_DOES_NOT_INCLUDE,
|
||||||
@ -126,6 +127,7 @@ const TEXT_FILTER_TARGET_ASN = 'asn'
|
|||||||
const TEXT_FILTER_TARGET_FULLTEXT_QUERY = 'fulltext-query'
|
const TEXT_FILTER_TARGET_FULLTEXT_QUERY = 'fulltext-query'
|
||||||
const TEXT_FILTER_TARGET_FULLTEXT_MORELIKE = 'fulltext-morelike'
|
const TEXT_FILTER_TARGET_FULLTEXT_MORELIKE = 'fulltext-morelike'
|
||||||
const TEXT_FILTER_TARGET_CUSTOM_FIELDS = 'custom-fields'
|
const TEXT_FILTER_TARGET_CUSTOM_FIELDS = 'custom-fields'
|
||||||
|
const TEXT_FILTER_TARGET_MIME_TYPE = 'mime-type'
|
||||||
|
|
||||||
const TEXT_FILTER_MODIFIER_EQUALS = 'equals'
|
const TEXT_FILTER_MODIFIER_EQUALS = 'equals'
|
||||||
const TEXT_FILTER_MODIFIER_NULL = 'is null'
|
const TEXT_FILTER_MODIFIER_NULL = 'is null'
|
||||||
@ -169,6 +171,7 @@ const DEFAULT_TEXT_FILTER_TARGET_OPTIONS = [
|
|||||||
id: TEXT_FILTER_TARGET_FULLTEXT_QUERY,
|
id: TEXT_FILTER_TARGET_FULLTEXT_QUERY,
|
||||||
name: $localize`Advanced search`,
|
name: $localize`Advanced search`,
|
||||||
},
|
},
|
||||||
|
{ id: TEXT_FILTER_TARGET_MIME_TYPE, name: $localize`MIME type` },
|
||||||
]
|
]
|
||||||
|
|
||||||
const TEXT_FILTER_TARGET_MORELIKE_OPTION = {
|
const TEXT_FILTER_TARGET_MORELIKE_OPTION = {
|
||||||
@ -416,6 +419,10 @@ export class FilterEditorComponent
|
|||||||
this._textFilter = rule.value
|
this._textFilter = rule.value
|
||||||
this.textFilterTarget = TEXT_FILTER_TARGET_CUSTOM_FIELDS
|
this.textFilterTarget = TEXT_FILTER_TARGET_CUSTOM_FIELDS
|
||||||
break
|
break
|
||||||
|
case FILTER_MIME_TYPE:
|
||||||
|
this.textFilterTarget = TEXT_FILTER_TARGET_MIME_TYPE
|
||||||
|
this._textFilter = rule.value
|
||||||
|
break
|
||||||
case FILTER_FULLTEXT_QUERY:
|
case FILTER_FULLTEXT_QUERY:
|
||||||
let allQueryArgs = rule.value.split(',')
|
let allQueryArgs = rule.value.split(',')
|
||||||
let textQueryArgs = []
|
let textQueryArgs = []
|
||||||
@ -729,6 +736,15 @@ export class FilterEditorComponent
|
|||||||
value: this._textFilter,
|
value: this._textFilter,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
this._textFilter &&
|
||||||
|
this.textFilterTarget == TEXT_FILTER_TARGET_MIME_TYPE
|
||||||
|
) {
|
||||||
|
filterRules.push({
|
||||||
|
rule_type: FILTER_MIME_TYPE,
|
||||||
|
value: this._textFilter,
|
||||||
|
})
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
this._textFilter &&
|
this._textFilter &&
|
||||||
this.textFilterTarget == TEXT_FILTER_TARGET_FULLTEXT_QUERY
|
this.textFilterTarget == TEXT_FILTER_TARGET_FULLTEXT_QUERY
|
||||||
|
@ -62,6 +62,8 @@ export const FILTER_HAS_ANY_CUSTOM_FIELDS = 41
|
|||||||
|
|
||||||
export const FILTER_CUSTOM_FIELDS_QUERY = 42
|
export const FILTER_CUSTOM_FIELDS_QUERY = 42
|
||||||
|
|
||||||
|
export const FILTER_MIME_TYPE = 43
|
||||||
|
|
||||||
export const FILTER_RULE_TYPES: FilterRuleType[] = [
|
export const FILTER_RULE_TYPES: FilterRuleType[] = [
|
||||||
{
|
{
|
||||||
id: FILTER_TITLE,
|
id: FILTER_TITLE,
|
||||||
@ -354,6 +356,12 @@ export const FILTER_RULE_TYPES: FilterRuleType[] = [
|
|||||||
datatype: 'string',
|
datatype: 'string',
|
||||||
multi: false,
|
multi: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: FILTER_MIME_TYPE,
|
||||||
|
filtervar: 'mime_type',
|
||||||
|
datatype: 'string',
|
||||||
|
multi: false,
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
export interface FilterRuleType {
|
export interface FilterRuleType {
|
||||||
|
@ -215,6 +215,14 @@ class CustomFieldsFilter(Filter):
|
|||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
|
||||||
|
class MimeTypeFilter(Filter):
|
||||||
|
def filter(self, qs, value):
|
||||||
|
if value:
|
||||||
|
return qs.filter(mime_type__icontains=value)
|
||||||
|
else:
|
||||||
|
return qs
|
||||||
|
|
||||||
|
|
||||||
class SelectField(serializers.CharField):
|
class SelectField(serializers.CharField):
|
||||||
def __init__(self, custom_field: CustomField):
|
def __init__(self, custom_field: CustomField):
|
||||||
self._options = custom_field.extra_data["select_options"]
|
self._options = custom_field.extra_data["select_options"]
|
||||||
@ -710,6 +718,8 @@ class DocumentFilterSet(FilterSet):
|
|||||||
|
|
||||||
shared_by__id = SharedByUser()
|
shared_by__id = SharedByUser()
|
||||||
|
|
||||||
|
mime_type = MimeTypeFilter()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Document
|
model = Document
|
||||||
fields = {
|
fields = {
|
||||||
|
@ -639,6 +639,13 @@ class TestDocumentApi(DirectoriesMixin, DocumentConsumeDelayMixin, APITestCase):
|
|||||||
self.assertEqual(len(results), 1)
|
self.assertEqual(len(results), 1)
|
||||||
self.assertEqual(results[0]["id"], doc3.id)
|
self.assertEqual(results[0]["id"], doc3.id)
|
||||||
|
|
||||||
|
response = self.client.get(
|
||||||
|
"/api/documents/?mime_type=pdf",
|
||||||
|
)
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
results = response.data["results"]
|
||||||
|
self.assertEqual(len(results), 3)
|
||||||
|
|
||||||
def test_custom_field_select_filter(self):
|
def test_custom_field_select_filter(self):
|
||||||
"""
|
"""
|
||||||
GIVEN:
|
GIVEN:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user