Custom field filtering
This commit is contained in:
@@ -68,6 +68,10 @@ const selectionData: SelectionData = {
|
||||
{ id: 66, document_count: 3 },
|
||||
{ id: 55, document_count: 0 },
|
||||
],
|
||||
selected_custom_fields: [
|
||||
{ id: 1, document_count: 3 },
|
||||
{ id: 2, document_count: 0 },
|
||||
],
|
||||
}
|
||||
|
||||
describe('BulkEditorComponent', () => {
|
||||
|
||||
@@ -70,6 +70,18 @@
|
||||
[documentCounts]="storagePathDocumentCounts"
|
||||
[allowSelectNone]="true"></pngx-filterable-dropdown>
|
||||
}
|
||||
|
||||
@if (permissionsService.currentUserCan(PermissionAction.View, PermissionType.CustomField)) {
|
||||
<pngx-filterable-dropdown class="flex-fill" title="Custom fields" icon="ui-radios" i18n-title
|
||||
filterPlaceholder="Filter custom fields" i18n-filterPlaceholder
|
||||
[items]="customFields"
|
||||
[manyToOne]="true"
|
||||
[(selectionModel)]="customFieldSelectionModel"
|
||||
(selectionModelChange)="updateRules()"
|
||||
(opened)="onCustomFieldsDropdownOpen()"
|
||||
[documentCounts]="customFieldDocumentCounts"
|
||||
[allowSelectNone]="true"></pngx-filterable-dropdown>
|
||||
}
|
||||
</div>
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<pngx-date-dropdown
|
||||
|
||||
@@ -49,8 +49,12 @@ import {
|
||||
FILTER_OWNER_ANY,
|
||||
FILTER_OWNER_DOES_NOT_INCLUDE,
|
||||
FILTER_OWNER_ISNULL,
|
||||
FILTER_CUSTOM_FIELDS,
|
||||
FILTER_CUSTOM_FIELDS_TEXT,
|
||||
FILTER_SHARED_BY_USER,
|
||||
FILTER_HAS_CUSTOM_FIELDS_ANY,
|
||||
FILTER_HAS_ANY_CUSTOM_FIELDS,
|
||||
FILTER_DOES_NOT_HAVE_CUSTOM_FIELDS,
|
||||
FILTER_HAS_CUSTOM_FIELDS_ALL,
|
||||
} from 'src/app/data/filter-rule-type'
|
||||
import { Correspondent } from 'src/app/data/correspondent'
|
||||
import { DocumentType } from 'src/app/data/document-type'
|
||||
@@ -86,6 +90,8 @@ import {
|
||||
PermissionsService,
|
||||
} from 'src/app/services/permissions.service'
|
||||
import { environment } from 'src/environments/environment'
|
||||
import { CustomField, CustomFieldDataType } from 'src/app/data/custom-field'
|
||||
import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
|
||||
|
||||
const tags: Tag[] = [
|
||||
{
|
||||
@@ -131,6 +137,19 @@ const storage_paths: StoragePath[] = [
|
||||
},
|
||||
]
|
||||
|
||||
const custom_fields: CustomField[] = [
|
||||
{
|
||||
id: 42,
|
||||
data_type: CustomFieldDataType.String,
|
||||
name: 'CustomField42',
|
||||
},
|
||||
{
|
||||
id: 43,
|
||||
data_type: CustomFieldDataType.String,
|
||||
name: 'CustomField43',
|
||||
},
|
||||
]
|
||||
|
||||
const users: User[] = [
|
||||
{
|
||||
id: 1,
|
||||
@@ -187,6 +206,12 @@ describe('FilterEditorComponent', () => {
|
||||
listAll: () => of({ results: storage_paths }),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: CustomFieldsService,
|
||||
useValue: {
|
||||
listAll: () => of({ results: custom_fields }),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: UserService,
|
||||
useValue: {
|
||||
@@ -285,7 +310,7 @@ describe('FilterEditorComponent', () => {
|
||||
expect(component.textFilter).toEqual(null)
|
||||
component.filterRules = [
|
||||
{
|
||||
rule_type: FILTER_CUSTOM_FIELDS,
|
||||
rule_type: FILTER_CUSTOM_FIELDS_TEXT,
|
||||
value: 'foo',
|
||||
},
|
||||
]
|
||||
@@ -806,6 +831,110 @@ describe('FilterEditorComponent', () => {
|
||||
]
|
||||
}))
|
||||
|
||||
it('should ingest filter rules for has all custom fields', fakeAsync(() => {
|
||||
expect(component.customFieldSelectionModel.getSelectedItems()).toHaveLength(
|
||||
0
|
||||
)
|
||||
component.filterRules = [
|
||||
{
|
||||
rule_type: FILTER_HAS_CUSTOM_FIELDS_ALL,
|
||||
value: '42',
|
||||
},
|
||||
{
|
||||
rule_type: FILTER_HAS_CUSTOM_FIELDS_ALL,
|
||||
value: '43',
|
||||
},
|
||||
]
|
||||
expect(component.customFieldSelectionModel.logicalOperator).toEqual(
|
||||
LogicalOperator.And
|
||||
)
|
||||
expect(component.customFieldSelectionModel.getSelectedItems()).toEqual(
|
||||
custom_fields
|
||||
)
|
||||
// coverage
|
||||
component.filterRules = [
|
||||
{
|
||||
rule_type: FILTER_HAS_CUSTOM_FIELDS_ALL,
|
||||
value: null,
|
||||
},
|
||||
]
|
||||
component.toggleTag(2) // coverage
|
||||
}))
|
||||
|
||||
it('should ingest filter rules for has any custom fields', fakeAsync(() => {
|
||||
expect(component.customFieldSelectionModel.getSelectedItems()).toHaveLength(
|
||||
0
|
||||
)
|
||||
component.filterRules = [
|
||||
{
|
||||
rule_type: FILTER_HAS_CUSTOM_FIELDS_ANY,
|
||||
value: '42',
|
||||
},
|
||||
{
|
||||
rule_type: FILTER_HAS_CUSTOM_FIELDS_ANY,
|
||||
value: '43',
|
||||
},
|
||||
]
|
||||
expect(component.customFieldSelectionModel.logicalOperator).toEqual(
|
||||
LogicalOperator.Or
|
||||
)
|
||||
expect(component.customFieldSelectionModel.getSelectedItems()).toEqual(
|
||||
custom_fields
|
||||
)
|
||||
// coverage
|
||||
component.filterRules = [
|
||||
{
|
||||
rule_type: FILTER_HAS_CUSTOM_FIELDS_ANY,
|
||||
value: null,
|
||||
},
|
||||
]
|
||||
}))
|
||||
|
||||
it('should ingest filter rules for has any custom field', fakeAsync(() => {
|
||||
expect(component.customFieldSelectionModel.getSelectedItems()).toHaveLength(
|
||||
0
|
||||
)
|
||||
component.filterRules = [
|
||||
{
|
||||
rule_type: FILTER_HAS_ANY_CUSTOM_FIELDS,
|
||||
value: '1',
|
||||
},
|
||||
]
|
||||
expect(component.customFieldSelectionModel.getSelectedItems()).toHaveLength(
|
||||
1
|
||||
)
|
||||
expect(component.customFieldSelectionModel.get(null)).toBeTruthy()
|
||||
}))
|
||||
|
||||
it('should ingest filter rules for exclude tag(s)', fakeAsync(() => {
|
||||
expect(component.customFieldSelectionModel.getExcludedItems()).toHaveLength(
|
||||
0
|
||||
)
|
||||
component.filterRules = [
|
||||
{
|
||||
rule_type: FILTER_DOES_NOT_HAVE_CUSTOM_FIELDS,
|
||||
value: '42',
|
||||
},
|
||||
{
|
||||
rule_type: FILTER_DOES_NOT_HAVE_CUSTOM_FIELDS,
|
||||
value: '43',
|
||||
},
|
||||
]
|
||||
expect(component.customFieldSelectionModel.logicalOperator).toEqual(
|
||||
LogicalOperator.And
|
||||
)
|
||||
expect(component.customFieldSelectionModel.getExcludedItems()).toEqual(
|
||||
custom_fields
|
||||
)
|
||||
// coverage
|
||||
component.filterRules = [
|
||||
{
|
||||
rule_type: FILTER_DOES_NOT_HAVE_CUSTOM_FIELDS,
|
||||
value: null,
|
||||
},
|
||||
]
|
||||
}))
|
||||
|
||||
it('should ingest filter rules for owner', fakeAsync(() => {
|
||||
expect(component.permissionsSelectionModel.ownerFilter).toEqual(
|
||||
OwnerFilterType.NONE
|
||||
@@ -1053,7 +1182,7 @@ describe('FilterEditorComponent', () => {
|
||||
expect(component.textFilterTarget).toEqual('custom-fields')
|
||||
expect(component.filterRules).toEqual([
|
||||
{
|
||||
rule_type: FILTER_CUSTOM_FIELDS,
|
||||
rule_type: FILTER_CUSTOM_FIELDS_TEXT,
|
||||
value: 'foo',
|
||||
},
|
||||
])
|
||||
@@ -1317,6 +1446,75 @@ describe('FilterEditorComponent', () => {
|
||||
])
|
||||
}))
|
||||
|
||||
it('should convert user input to correct filter rules on custom field select not assigned', fakeAsync(() => {
|
||||
const customFieldsFilterableDropdown = fixture.debugElement.queryAll(
|
||||
By.directive(FilterableDropdownComponent)
|
||||
)[4]
|
||||
customFieldsFilterableDropdown.triggerEventHandler('opened')
|
||||
const customFieldButton = customFieldsFilterableDropdown.queryAll(
|
||||
By.directive(ToggleableDropdownButtonComponent)
|
||||
)[0]
|
||||
customFieldButton.triggerEventHandler('toggle')
|
||||
fixture.detectChanges()
|
||||
expect(component.filterRules).toEqual([
|
||||
{
|
||||
rule_type: FILTER_HAS_ANY_CUSTOM_FIELDS,
|
||||
value: 'false',
|
||||
},
|
||||
])
|
||||
}))
|
||||
|
||||
it('should convert user input to correct filter rules on custom field selections', fakeAsync(() => {
|
||||
const customFieldsFilterableDropdown = fixture.debugElement.queryAll(
|
||||
By.directive(FilterableDropdownComponent)
|
||||
)[4] // CF dropdown
|
||||
customFieldsFilterableDropdown.triggerEventHandler('opened')
|
||||
const customFieldButtons = customFieldsFilterableDropdown.queryAll(
|
||||
By.directive(ToggleableDropdownButtonComponent)
|
||||
)
|
||||
customFieldButtons[1].triggerEventHandler('toggle')
|
||||
customFieldButtons[2].triggerEventHandler('toggle')
|
||||
fixture.detectChanges()
|
||||
expect(component.filterRules).toEqual([
|
||||
{
|
||||
rule_type: FILTER_HAS_CUSTOM_FIELDS_ALL,
|
||||
value: custom_fields[0].id.toString(),
|
||||
},
|
||||
{
|
||||
rule_type: FILTER_HAS_CUSTOM_FIELDS_ALL,
|
||||
value: custom_fields[1].id.toString(),
|
||||
},
|
||||
])
|
||||
const toggleOperatorButtons = customFieldsFilterableDropdown.queryAll(
|
||||
By.css('input[type=radio]')
|
||||
)
|
||||
toggleOperatorButtons[1].nativeElement.checked = true
|
||||
toggleOperatorButtons[1].triggerEventHandler('change')
|
||||
fixture.detectChanges()
|
||||
expect(component.filterRules).toEqual([
|
||||
{
|
||||
rule_type: FILTER_HAS_CUSTOM_FIELDS_ANY,
|
||||
value: custom_fields[0].id.toString(),
|
||||
},
|
||||
{
|
||||
rule_type: FILTER_HAS_CUSTOM_FIELDS_ANY,
|
||||
value: custom_fields[1].id.toString(),
|
||||
},
|
||||
])
|
||||
customFieldButtons[2].triggerEventHandler('exclude')
|
||||
fixture.detectChanges()
|
||||
expect(component.filterRules).toEqual([
|
||||
{
|
||||
rule_type: FILTER_HAS_CUSTOM_FIELDS_ALL,
|
||||
value: custom_fields[0].id.toString(),
|
||||
},
|
||||
{
|
||||
rule_type: FILTER_DOES_NOT_HAVE_CUSTOM_FIELDS,
|
||||
value: custom_fields[1].id.toString(),
|
||||
},
|
||||
])
|
||||
}))
|
||||
|
||||
it('should convert user input to correct filter rules on date created after', fakeAsync(() => {
|
||||
const dateCreatedDropdown = fixture.debugElement.queryAll(
|
||||
By.directive(DateDropdownComponent)
|
||||
@@ -1645,6 +1843,10 @@ describe('FilterEditorComponent', () => {
|
||||
{ id: 32, document_count: 1 },
|
||||
{ id: 33, document_count: 0 },
|
||||
],
|
||||
selected_custom_fields: [
|
||||
{ id: 42, document_count: 1 },
|
||||
{ id: 43, document_count: 0 },
|
||||
],
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1719,6 +1921,24 @@ describe('FilterEditorComponent', () => {
|
||||
]
|
||||
expect(component.generateFilterName()).toEqual('Without any tag')
|
||||
|
||||
component.filterRules = [
|
||||
{
|
||||
rule_type: FILTER_HAS_CUSTOM_FIELDS_ALL,
|
||||
value: '42',
|
||||
},
|
||||
]
|
||||
expect(component.generateFilterName()).toEqual(
|
||||
`Custom fields: ${custom_fields[0].name}`
|
||||
)
|
||||
|
||||
component.filterRules = [
|
||||
{
|
||||
rule_type: FILTER_HAS_ANY_CUSTOM_FIELDS,
|
||||
value: 'false',
|
||||
},
|
||||
]
|
||||
expect(component.generateFilterName()).toEqual('Without any custom field')
|
||||
|
||||
component.filterRules = [
|
||||
{
|
||||
rule_type: FILTER_TITLE,
|
||||
|
||||
@@ -48,8 +48,12 @@ import {
|
||||
FILTER_OWNER_DOES_NOT_INCLUDE,
|
||||
FILTER_OWNER_ISNULL,
|
||||
FILTER_OWNER_ANY,
|
||||
FILTER_CUSTOM_FIELDS,
|
||||
FILTER_CUSTOM_FIELDS_TEXT,
|
||||
FILTER_SHARED_BY_USER,
|
||||
FILTER_HAS_CUSTOM_FIELDS_ANY,
|
||||
FILTER_HAS_CUSTOM_FIELDS_ALL,
|
||||
FILTER_HAS_ANY_CUSTOM_FIELDS,
|
||||
FILTER_DOES_NOT_HAVE_CUSTOM_FIELDS,
|
||||
} from 'src/app/data/filter-rule-type'
|
||||
import {
|
||||
FilterableDropdownSelectionModel,
|
||||
@@ -76,6 +80,8 @@ import {
|
||||
PermissionsService,
|
||||
} from 'src/app/services/permissions.service'
|
||||
import { ComponentWithPermissions } from '../../with-permissions/with-permissions.component'
|
||||
import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
|
||||
import { CustomField } from 'src/app/data/custom-field'
|
||||
|
||||
const TEXT_FILTER_TARGET_TITLE = 'title'
|
||||
const TEXT_FILTER_TARGET_TITLE_CONTENT = 'title-content'
|
||||
@@ -208,6 +214,16 @@ export class FilterEditorComponent
|
||||
return $localize`Without any tag`
|
||||
}
|
||||
|
||||
case FILTER_HAS_CUSTOM_FIELDS_ALL:
|
||||
return $localize`Custom fields: ${this.customFields.find(
|
||||
(f) => f.id == +rule.value
|
||||
)?.name}`
|
||||
|
||||
case FILTER_HAS_ANY_CUSTOM_FIELDS:
|
||||
if (rule.value == 'false') {
|
||||
return $localize`Without any custom field`
|
||||
}
|
||||
|
||||
case FILTER_TITLE:
|
||||
return $localize`Title: ${rule.value}`
|
||||
|
||||
@@ -234,7 +250,8 @@ export class FilterEditorComponent
|
||||
private correspondentService: CorrespondentService,
|
||||
private documentService: DocumentService,
|
||||
private storagePathService: StoragePathService,
|
||||
public permissionsService: PermissionsService
|
||||
public permissionsService: PermissionsService,
|
||||
private customFieldService: CustomFieldsService
|
||||
) {
|
||||
super()
|
||||
}
|
||||
@@ -246,11 +263,13 @@ export class FilterEditorComponent
|
||||
correspondents: Correspondent[] = []
|
||||
documentTypes: DocumentType[] = []
|
||||
storagePaths: StoragePath[] = []
|
||||
customFields: CustomField[] = []
|
||||
|
||||
tagDocumentCounts: SelectionDataItem[]
|
||||
correspondentDocumentCounts: SelectionDataItem[]
|
||||
documentTypeDocumentCounts: SelectionDataItem[]
|
||||
storagePathDocumentCounts: SelectionDataItem[]
|
||||
customFieldDocumentCounts: SelectionDataItem[]
|
||||
|
||||
_textFilter = ''
|
||||
_moreLikeId: number
|
||||
@@ -288,6 +307,7 @@ export class FilterEditorComponent
|
||||
correspondentSelectionModel = new FilterableDropdownSelectionModel()
|
||||
documentTypeSelectionModel = new FilterableDropdownSelectionModel()
|
||||
storagePathSelectionModel = new FilterableDropdownSelectionModel()
|
||||
customFieldSelectionModel = new FilterableDropdownSelectionModel()
|
||||
|
||||
dateCreatedBefore: string
|
||||
dateCreatedAfter: string
|
||||
@@ -322,6 +342,7 @@ export class FilterEditorComponent
|
||||
this.storagePathSelectionModel.clear(false)
|
||||
this.tagSelectionModel.clear(false)
|
||||
this.correspondentSelectionModel.clear(false)
|
||||
this.customFieldSelectionModel.clear(false)
|
||||
this._textFilter = null
|
||||
this._moreLikeId = null
|
||||
this.dateAddedBefore = null
|
||||
@@ -347,7 +368,7 @@ export class FilterEditorComponent
|
||||
this._textFilter = rule.value
|
||||
this.textFilterTarget = TEXT_FILTER_TARGET_ASN
|
||||
break
|
||||
case FILTER_CUSTOM_FIELDS:
|
||||
case FILTER_CUSTOM_FIELDS_TEXT:
|
||||
this._textFilter = rule.value
|
||||
this.textFilterTarget = TEXT_FILTER_TARGET_CUSTOM_FIELDS
|
||||
break
|
||||
@@ -488,6 +509,36 @@ export class FilterEditorComponent
|
||||
false
|
||||
)
|
||||
break
|
||||
case FILTER_HAS_CUSTOM_FIELDS_ALL:
|
||||
this.customFieldSelectionModel.logicalOperator = LogicalOperator.And
|
||||
this.customFieldSelectionModel.set(
|
||||
rule.value ? +rule.value : null,
|
||||
ToggleableItemState.Selected,
|
||||
false
|
||||
)
|
||||
break
|
||||
case FILTER_HAS_CUSTOM_FIELDS_ANY:
|
||||
this.customFieldSelectionModel.logicalOperator = LogicalOperator.Or
|
||||
this.customFieldSelectionModel.set(
|
||||
rule.value ? +rule.value : null,
|
||||
ToggleableItemState.Selected,
|
||||
false
|
||||
)
|
||||
break
|
||||
case FILTER_HAS_ANY_CUSTOM_FIELDS:
|
||||
this.customFieldSelectionModel.set(
|
||||
null,
|
||||
ToggleableItemState.Selected,
|
||||
false
|
||||
)
|
||||
break
|
||||
case FILTER_DOES_NOT_HAVE_CUSTOM_FIELDS:
|
||||
this.customFieldSelectionModel.set(
|
||||
rule.value ? +rule.value : null,
|
||||
ToggleableItemState.Excluded,
|
||||
false
|
||||
)
|
||||
break
|
||||
case FILTER_ASN_ISNULL:
|
||||
this.textFilterTarget = TEXT_FILTER_TARGET_ASN
|
||||
this.textFilterModifier =
|
||||
@@ -595,7 +646,7 @@ export class FilterEditorComponent
|
||||
this.textFilterTarget == TEXT_FILTER_TARGET_CUSTOM_FIELDS
|
||||
) {
|
||||
filterRules.push({
|
||||
rule_type: FILTER_CUSTOM_FIELDS,
|
||||
rule_type: FILTER_CUSTOM_FIELDS_TEXT,
|
||||
value: this._textFilter,
|
||||
})
|
||||
}
|
||||
@@ -703,6 +754,35 @@ export class FilterEditorComponent
|
||||
})
|
||||
})
|
||||
}
|
||||
if (this.customFieldSelectionModel.isNoneSelected()) {
|
||||
filterRules.push({
|
||||
rule_type: FILTER_HAS_ANY_CUSTOM_FIELDS,
|
||||
value: 'false',
|
||||
})
|
||||
} else {
|
||||
const customFieldFilterType =
|
||||
this.customFieldSelectionModel.logicalOperator == LogicalOperator.And
|
||||
? FILTER_HAS_CUSTOM_FIELDS_ALL
|
||||
: FILTER_HAS_CUSTOM_FIELDS_ANY
|
||||
this.customFieldSelectionModel
|
||||
.getSelectedItems()
|
||||
.filter((field) => field.id)
|
||||
.forEach((field) => {
|
||||
filterRules.push({
|
||||
rule_type: customFieldFilterType,
|
||||
value: field.id?.toString(),
|
||||
})
|
||||
})
|
||||
this.customFieldSelectionModel
|
||||
.getExcludedItems()
|
||||
.filter((field) => field.id)
|
||||
.forEach((field) => {
|
||||
filterRules.push({
|
||||
rule_type: FILTER_DOES_NOT_HAVE_CUSTOM_FIELDS,
|
||||
value: field.id?.toString(),
|
||||
})
|
||||
})
|
||||
}
|
||||
if (this.dateCreatedBefore) {
|
||||
filterRules.push({
|
||||
rule_type: FILTER_CREATED_BEFORE,
|
||||
@@ -845,6 +925,8 @@ export class FilterEditorComponent
|
||||
selectionData?.selected_correspondents ?? null
|
||||
this.storagePathDocumentCounts =
|
||||
selectionData?.selected_storage_paths ?? null
|
||||
this.customFieldDocumentCounts =
|
||||
selectionData?.selected_custom_fields ?? null
|
||||
}
|
||||
|
||||
rulesModified: boolean = false
|
||||
@@ -905,6 +987,16 @@ export class FilterEditorComponent
|
||||
.listAll()
|
||||
.subscribe((result) => (this.storagePaths = result.results))
|
||||
}
|
||||
if (
|
||||
this.permissionsService.currentUserCan(
|
||||
PermissionAction.View,
|
||||
PermissionType.CustomField
|
||||
)
|
||||
) {
|
||||
this.customFieldService
|
||||
.listAll()
|
||||
.subscribe((result) => (this.customFields = result.results))
|
||||
}
|
||||
|
||||
this.textFilterDebounce = new Subject<string>()
|
||||
|
||||
@@ -961,6 +1053,10 @@ export class FilterEditorComponent
|
||||
this.storagePathSelectionModel.apply()
|
||||
}
|
||||
|
||||
onCustomFieldsDropdownOpen() {
|
||||
this.customFieldSelectionModel.apply()
|
||||
}
|
||||
|
||||
updateTextFilter(text) {
|
||||
this._textFilter = text
|
||||
this.documentService.searchQuery = text
|
||||
|
||||
@@ -47,7 +47,11 @@ export const FILTER_OWNER_ISNULL = 34
|
||||
export const FILTER_OWNER_DOES_NOT_INCLUDE = 35
|
||||
export const FILTER_SHARED_BY_USER = 37
|
||||
|
||||
export const FILTER_CUSTOM_FIELDS = 36
|
||||
export const FILTER_CUSTOM_FIELDS_TEXT = 36
|
||||
export const FILTER_HAS_CUSTOM_FIELDS_ALL = 38
|
||||
export const FILTER_HAS_CUSTOM_FIELDS_ANY = 39
|
||||
export const FILTER_DOES_NOT_HAVE_CUSTOM_FIELDS = 40
|
||||
export const FILTER_HAS_ANY_CUSTOM_FIELDS = 41
|
||||
|
||||
export const FILTER_RULE_TYPES: FilterRuleType[] = [
|
||||
{
|
||||
@@ -281,11 +285,36 @@ export const FILTER_RULE_TYPES: FilterRuleType[] = [
|
||||
multi: true,
|
||||
},
|
||||
{
|
||||
id: FILTER_CUSTOM_FIELDS,
|
||||
id: FILTER_CUSTOM_FIELDS_TEXT,
|
||||
filtervar: 'custom_fields__icontains',
|
||||
datatype: 'string',
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
id: FILTER_HAS_CUSTOM_FIELDS_ALL,
|
||||
filtervar: 'custom_fields__id__all',
|
||||
datatype: 'number',
|
||||
multi: true,
|
||||
},
|
||||
{
|
||||
id: FILTER_HAS_CUSTOM_FIELDS_ANY,
|
||||
filtervar: 'custom_fields__id__in',
|
||||
datatype: 'number',
|
||||
multi: true,
|
||||
},
|
||||
{
|
||||
id: FILTER_DOES_NOT_HAVE_CUSTOM_FIELDS,
|
||||
filtervar: 'custom_fields__id__none',
|
||||
datatype: 'number',
|
||||
multi: true,
|
||||
},
|
||||
{
|
||||
id: FILTER_HAS_ANY_CUSTOM_FIELDS,
|
||||
filtervar: 'has_custom_fields',
|
||||
datatype: 'boolean',
|
||||
multi: false,
|
||||
default: true,
|
||||
},
|
||||
]
|
||||
|
||||
export interface FilterRuleType {
|
||||
|
||||
@@ -36,6 +36,7 @@ export interface SelectionData {
|
||||
selected_correspondents: SelectionDataItem[]
|
||||
selected_tags: SelectionDataItem[]
|
||||
selected_document_types: SelectionDataItem[]
|
||||
selected_custom_fields: SelectionDataItem[]
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
|
||||
Reference in New Issue
Block a user