Gotta start somewhere

This commit is contained in:
shamoon
2024-09-01 00:29:52 -07:00
parent d7ba6d98d3
commit f0157a36fb
9 changed files with 275 additions and 101 deletions

View File

@@ -86,15 +86,10 @@
}
@if (permissionsService.currentUserCan(PermissionAction.View, PermissionType.CustomField) && customFields.length > 0) {
<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"
<pngx-custom-fields-lookup-dropdown class="flex-fill" title="Custom fields" icon="ui-radios" i18n-title
[(selectionModel)]="customFieldQueriesModel"
(selectionModelChange)="updateRules()"
(opened)="onCustomFieldsDropdownOpen()"
[documentCounts]="customFieldDocumentCounts"
[allowSelectNone]="true"></pngx-filterable-dropdown>
></pngx-custom-fields-lookup-dropdown>
}
<pngx-dates-dropdown
title="Dates" i18n-title

View File

@@ -839,9 +839,7 @@ describe('FilterEditorComponent', () => {
}))
it('should ingest filter rules for has all custom fields', fakeAsync(() => {
expect(component.customFieldSelectionModel.getSelectedItems()).toHaveLength(
0
)
expect(component.customFieldQueriesModel.getSelectedItems()).toHaveLength(0)
component.filterRules = [
{
rule_type: FILTER_HAS_CUSTOM_FIELDS_ALL,
@@ -852,10 +850,10 @@ describe('FilterEditorComponent', () => {
value: '43',
},
]
expect(component.customFieldSelectionModel.logicalOperator).toEqual(
expect(component.customFieldQueriesModel.logicalOperator).toEqual(
LogicalOperator.And
)
expect(component.customFieldSelectionModel.getSelectedItems()).toEqual(
expect(component.customFieldQueriesModel.getSelectedItems()).toEqual(
custom_fields
)
// coverage
@@ -869,9 +867,7 @@ describe('FilterEditorComponent', () => {
}))
it('should ingest filter rules for has any custom fields', fakeAsync(() => {
expect(component.customFieldSelectionModel.getSelectedItems()).toHaveLength(
0
)
expect(component.customFieldQueriesModel.getSelectedItems()).toHaveLength(0)
component.filterRules = [
{
rule_type: FILTER_HAS_CUSTOM_FIELDS_ANY,
@@ -882,10 +878,10 @@ describe('FilterEditorComponent', () => {
value: '43',
},
]
expect(component.customFieldSelectionModel.logicalOperator).toEqual(
expect(component.customFieldQueriesModel.logicalOperator).toEqual(
LogicalOperator.Or
)
expect(component.customFieldSelectionModel.getSelectedItems()).toEqual(
expect(component.customFieldQueriesModel.getSelectedItems()).toEqual(
custom_fields
)
// coverage
@@ -898,25 +894,19 @@ describe('FilterEditorComponent', () => {
}))
it('should ingest filter rules for has any custom field', fakeAsync(() => {
expect(component.customFieldSelectionModel.getSelectedItems()).toHaveLength(
0
)
expect(component.customFieldQueriesModel.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()
expect(component.customFieldQueriesModel.getSelectedItems()).toHaveLength(1)
expect(component.customFieldQueriesModel.get(null)).toBeTruthy()
}))
it('should ingest filter rules for exclude tag(s)', fakeAsync(() => {
expect(component.customFieldSelectionModel.getExcludedItems()).toHaveLength(
0
)
expect(component.customFieldQueriesModel.getExcludedItems()).toHaveLength(0)
component.filterRules = [
{
rule_type: FILTER_DOES_NOT_HAVE_CUSTOM_FIELDS,
@@ -927,10 +917,10 @@ describe('FilterEditorComponent', () => {
value: '43',
},
]
expect(component.customFieldSelectionModel.logicalOperator).toEqual(
expect(component.customFieldQueriesModel.logicalOperator).toEqual(
LogicalOperator.And
)
expect(component.customFieldSelectionModel.getExcludedItems()).toEqual(
expect(component.customFieldQueriesModel.getExcludedItems()).toEqual(
custom_fields
)
// coverage

View File

@@ -12,7 +12,7 @@ import {
import { Tag } from 'src/app/data/tag'
import { Correspondent } from 'src/app/data/correspondent'
import { DocumentType } from 'src/app/data/document-type'
import { Observable, Subject, Subscription, from } from 'rxjs'
import { Observable, Subject, from } from 'rxjs'
import {
catchError,
debounceTime,
@@ -63,6 +63,7 @@ import {
FILTER_HAS_CUSTOM_FIELDS_ALL,
FILTER_HAS_ANY_CUSTOM_FIELDS,
FILTER_DOES_NOT_HAVE_CUSTOM_FIELDS,
FILTER_CUSTOM_FIELDS_LOOKUP,
} from 'src/app/data/filter-rule-type'
import {
FilterableDropdownSelectionModel,
@@ -92,13 +93,16 @@ import { ComponentWithPermissions } from '../../with-permissions/with-permission
import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
import { CustomField } from 'src/app/data/custom-field'
import { SearchService } from 'src/app/services/rest/search.service'
import {
CustomFieldQueriesModel,
CustomFieldQuery,
} from '../../common/custom-fields-lookup-dropdown/custom-fields-lookup-dropdown.component'
const TEXT_FILTER_TARGET_TITLE = 'title'
const TEXT_FILTER_TARGET_TITLE_CONTENT = 'title-content'
const TEXT_FILTER_TARGET_ASN = 'asn'
const TEXT_FILTER_TARGET_FULLTEXT_QUERY = 'fulltext-query'
const TEXT_FILTER_TARGET_FULLTEXT_MORELIKE = 'fulltext-morelike'
const TEXT_FILTER_TARGET_CUSTOM_FIELDS = 'custom-fields'
const TEXT_FILTER_MODIFIER_EQUALS = 'equals'
const TEXT_FILTER_MODIFIER_NULL = 'is null'
@@ -134,10 +138,6 @@ const DEFAULT_TEXT_FILTER_TARGET_OPTIONS = [
name: $localize`Title & content`,
},
{ id: TEXT_FILTER_TARGET_ASN, name: $localize`ASN` },
{
id: TEXT_FILTER_TARGET_CUSTOM_FIELDS,
name: $localize`Custom fields`,
},
{
id: TEXT_FILTER_TARGET_FULLTEXT_QUERY,
name: $localize`Advanced search`,
@@ -321,7 +321,7 @@ export class FilterEditorComponent
correspondentSelectionModel = new FilterableDropdownSelectionModel()
documentTypeSelectionModel = new FilterableDropdownSelectionModel()
storagePathSelectionModel = new FilterableDropdownSelectionModel()
customFieldSelectionModel = new FilterableDropdownSelectionModel()
customFieldQueriesModel = new CustomFieldQueriesModel()
dateCreatedBefore: string
dateCreatedAfter: string
@@ -356,7 +356,7 @@ export class FilterEditorComponent
this.storagePathSelectionModel.clear(false)
this.tagSelectionModel.clear(false)
this.correspondentSelectionModel.clear(false)
this.customFieldSelectionModel.clear(false)
this.customFieldQueriesModel.clear(false)
this._textFilter = null
this._moreLikeId = null
this.dateAddedBefore = null
@@ -383,8 +383,7 @@ export class FilterEditorComponent
this.textFilterTarget = TEXT_FILTER_TARGET_ASN
break
case FILTER_CUSTOM_FIELDS_TEXT:
this._textFilter = rule.value
this.textFilterTarget = TEXT_FILTER_TARGET_CUSTOM_FIELDS
console.log('FILTER_CUSTOM_FIELDS_TEXT', rule.value)
break
case FILTER_FULLTEXT_QUERY:
let allQueryArgs = rule.value.split(',')
@@ -523,35 +522,28 @@ 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
case FILTER_CUSTOM_FIELDS_LOOKUP:
// TODO: fully implement
const query = JSON.parse(rule.value)
this.customFieldQueriesModel.addQuery(
new CustomFieldQuery(query[0], query[1], query[2])
)
break
case FILTER_HAS_CUSTOM_FIELDS_ALL:
console.log('FILTER_HAS_CUSTOM_FIELDS_ALL', rule.value)
// TODO: fully implement
break
case FILTER_HAS_CUSTOM_FIELDS_ANY:
this.customFieldSelectionModel.logicalOperator = LogicalOperator.Or
this.customFieldSelectionModel.set(
rule.value ? +rule.value : null,
ToggleableItemState.Selected,
false
)
console.log('FILTER_HAS_CUSTOM_FIELDS_ANY', rule.value)
// TODO: fully implement
break
case FILTER_HAS_ANY_CUSTOM_FIELDS:
this.customFieldSelectionModel.set(
null,
ToggleableItemState.Selected,
false
)
console.log('FILTER_HAS_ANY_CUSTOM_FIELDS', rule.value)
// TODO: fully implement
break
case FILTER_DOES_NOT_HAVE_CUSTOM_FIELDS:
this.customFieldSelectionModel.set(
rule.value ? +rule.value : null,
ToggleableItemState.Excluded,
false
)
console.log('FILTER_DOES_NOT_HAVE_CUSTOM_FIELDS', rule.value)
// TODO: fully implement
break
case FILTER_ASN_ISNULL:
this.textFilterTarget = TEXT_FILTER_TARGET_ASN
@@ -655,15 +647,6 @@ export class FilterEditorComponent
})
}
}
if (
this._textFilter &&
this.textFilterTarget == TEXT_FILTER_TARGET_CUSTOM_FIELDS
) {
filterRules.push({
rule_type: FILTER_CUSTOM_FIELDS_TEXT,
value: this._textFilter,
})
}
if (
this._textFilter &&
this.textFilterTarget == TEXT_FILTER_TARGET_FULLTEXT_QUERY
@@ -768,35 +751,24 @@ export class FilterEditorComponent
})
})
}
if (this.customFieldSelectionModel.isNoneSelected()) {
let queries = this.customFieldQueriesModel.queries
.filter((query) => query.field && query.operator)
.map((query) => [query.field, query.operator, query.value])
console.log(
'this.customFieldQueriesModel.queries',
this.customFieldQueriesModel.queries
)
console.log('queries', queries)
if (queries.length > 0) {
filterRules.push({
rule_type: FILTER_HAS_ANY_CUSTOM_FIELDS,
value: 'false',
rule_type: FILTER_CUSTOM_FIELDS_LOOKUP,
value:
queries.length === 1
? JSON.stringify(queries[0])
: JSON.stringify(queries),
})
} 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(),
})
})
}
// TODO: fully implement custom fields
if (this.dateCreatedBefore) {
filterRules.push({
rule_type: FILTER_CREATED_BEFORE,
@@ -1079,10 +1051,6 @@ export class FilterEditorComponent
this.storagePathSelectionModel.apply()
}
onCustomFieldsDropdownOpen() {
this.customFieldSelectionModel.apply()
}
updateTextFilter(text, updateRules = true) {
this._textFilter = text
if (updateRules) {