Refactor, actual operator selections
This commit is contained in:
@@ -42,13 +42,13 @@
|
||||
bindValue="id"
|
||||
></ng-select>
|
||||
<select class="w-25 form-select" [(ngModel)]="query.operator" [disabled]="disabled">
|
||||
<option *ngFor="let operator of getOperatorsForField(query.field)" [ngValue]="operator">{{operator}}</option>
|
||||
<option *ngFor="let operator of getOperatorsForField(query.field)" [ngValue]="operator.value">{{operator.label}}</option>
|
||||
</select>
|
||||
@switch (query.operator) {
|
||||
@case ('exists') {
|
||||
@case (CustomFieldQueryOperator.Exists) {
|
||||
<select class="w-25 form-select rounded-end" [(ngModel)]="query.value" [disabled]="disabled">
|
||||
<option value="true" i18n>true</option>
|
||||
<option value="false" i18n>false</option>
|
||||
<option value="true" i18n>True</option>
|
||||
<option value="false" i18n>False</option>
|
||||
</select>
|
||||
}
|
||||
@default {
|
||||
|
||||
@@ -1,136 +1,18 @@
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core'
|
||||
import { Subject, first, takeUntil } from 'rxjs'
|
||||
import { CustomField } from 'src/app/data/custom-field'
|
||||
import {
|
||||
CustomFieldQueryAtom,
|
||||
CustomFieldQueryExpression,
|
||||
CustomFieldQueryElementType,
|
||||
CustomFieldQueryOperator,
|
||||
CUSTOM_FIELD_QUERY_OPERATOR_GROUPS_BY_TYPE,
|
||||
CUSTOM_FIELD_QUERY_OPERATORS_BY_GROUP,
|
||||
CustomFieldQueryOperatorGroups,
|
||||
CUSTOM_FIELD_QUERY_OPERATOR_LABELS,
|
||||
} from 'src/app/data/custom-field-query'
|
||||
import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
|
||||
|
||||
export enum CustomFieldQueryLogicalOperator {
|
||||
And = 'AND',
|
||||
Or = 'OR',
|
||||
Not = 'NOT',
|
||||
}
|
||||
|
||||
export enum CustomFieldQueryElementType {
|
||||
Atom = 'Atom',
|
||||
Expression = 'Expression',
|
||||
}
|
||||
|
||||
export class CustomFieldQueryElement {
|
||||
public readonly type: CustomFieldQueryElementType
|
||||
public changed: Subject<CustomFieldQueryElement>
|
||||
|
||||
constructor(type: CustomFieldQueryElementType) {
|
||||
this.type = type
|
||||
this.changed = new Subject<CustomFieldQueryElement>()
|
||||
}
|
||||
|
||||
public serialize() {
|
||||
throw new Error('Implemented in subclass')
|
||||
}
|
||||
|
||||
public get isValid(): boolean {
|
||||
throw new Error('Implemented in subclass')
|
||||
}
|
||||
|
||||
protected _operator: string = null
|
||||
set operator(value: string) {
|
||||
this._operator = value
|
||||
this.changed.next(this)
|
||||
}
|
||||
get operator(): string {
|
||||
return this._operator
|
||||
}
|
||||
|
||||
protected _value:
|
||||
| string
|
||||
| CustomFieldQueryAtom[]
|
||||
| CustomFieldQueryExpression[] = null
|
||||
set value(
|
||||
value: string | CustomFieldQueryAtom[] | CustomFieldQueryExpression[]
|
||||
) {
|
||||
this._value = value
|
||||
this.changed.next(this)
|
||||
}
|
||||
get value(): string | CustomFieldQueryAtom[] | CustomFieldQueryExpression[] {
|
||||
return this._value
|
||||
}
|
||||
}
|
||||
|
||||
export class CustomFieldQueryAtom extends CustomFieldQueryElement {
|
||||
protected _field: string
|
||||
set field(value: string) {
|
||||
this._field = value
|
||||
if (this.isValid) this.changed.next(this)
|
||||
}
|
||||
get field(): string {
|
||||
return this._field
|
||||
}
|
||||
|
||||
constructor(queryArray: [string, string, string] = [null, null, null]) {
|
||||
super(CustomFieldQueryElementType.Atom)
|
||||
;[this._field, this._operator, this._value] = queryArray
|
||||
}
|
||||
|
||||
public serialize() {
|
||||
return [this._field, this._operator, this._value]
|
||||
}
|
||||
|
||||
public get isValid(): boolean {
|
||||
return !!(this._field && this._operator && this._value !== null)
|
||||
}
|
||||
}
|
||||
|
||||
export class CustomFieldQueryExpression extends CustomFieldQueryElement {
|
||||
constructor(
|
||||
expressionArray: [CustomFieldQueryLogicalOperator, any[]] = [
|
||||
CustomFieldQueryLogicalOperator.And,
|
||||
null,
|
||||
]
|
||||
) {
|
||||
super(CustomFieldQueryElementType.Expression)
|
||||
;[this._operator] = expressionArray
|
||||
let values = expressionArray[1]
|
||||
if (!values) {
|
||||
this._value = []
|
||||
} else if (values?.length > 0 && values[0] instanceof Array) {
|
||||
this._value = values.map((value) => {
|
||||
if (value.length === 3) {
|
||||
const atom = new CustomFieldQueryAtom(value)
|
||||
atom.changed.subscribe(() => {
|
||||
this.changed.next(this)
|
||||
})
|
||||
return atom
|
||||
} else {
|
||||
const expression = new CustomFieldQueryExpression(value)
|
||||
expression.changed.subscribe(() => {
|
||||
this.changed.next(this)
|
||||
})
|
||||
return expression
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this._value = [new CustomFieldQueryExpression(values as any)]
|
||||
}
|
||||
}
|
||||
|
||||
public serialize() {
|
||||
let value
|
||||
if (this._value instanceof Array) {
|
||||
value = this._value.map((atom) => atom.serialize())
|
||||
} else {
|
||||
value = value.serialize()
|
||||
}
|
||||
return [this._operator, value]
|
||||
}
|
||||
|
||||
public get isValid(): boolean {
|
||||
return (
|
||||
this._operator &&
|
||||
this._value.length > 0 &&
|
||||
(this._value as any[]).every((v) => v.isValid)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export class CustomFieldQueriesModel {
|
||||
public queries: Array<CustomFieldQueryAtom | CustomFieldQueryExpression> = []
|
||||
|
||||
@@ -234,6 +116,7 @@ export class CustomFieldQueriesModel {
|
||||
})
|
||||
export class CustomFieldsQueryDropdownComponent {
|
||||
public CustomFieldQueryComponentType = CustomFieldQueryElementType
|
||||
public CustomFieldQueryOperator = CustomFieldQueryOperator
|
||||
|
||||
@Input()
|
||||
title: string
|
||||
@@ -317,8 +200,21 @@ export class CustomFieldsQueryDropdownComponent {
|
||||
this.selectionModel.clear()
|
||||
}
|
||||
|
||||
getOperatorsForField(field: CustomField): string[] {
|
||||
return ['exact', 'in', 'icontains', 'isnull', 'exists']
|
||||
// TODO: implement this
|
||||
getOperatorsForField(
|
||||
fieldID: number
|
||||
): Array<{ value: string; label: string }> {
|
||||
const field = this.customFields.find((field) => field.id === fieldID)
|
||||
const groups: CustomFieldQueryOperatorGroups[] =
|
||||
CUSTOM_FIELD_QUERY_OPERATOR_GROUPS_BY_TYPE[field.data_type]
|
||||
if (!groups) {
|
||||
return []
|
||||
}
|
||||
const operators = groups.flatMap(
|
||||
(group) => CUSTOM_FIELD_QUERY_OPERATORS_BY_GROUP[group]
|
||||
)
|
||||
return operators.map((operator) => ({
|
||||
value: operator,
|
||||
label: CUSTOM_FIELD_QUERY_OPERATOR_LABELS[operator],
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,11 +94,10 @@ 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,
|
||||
CustomFieldQueryAtom,
|
||||
CustomFieldQueryExpression,
|
||||
CustomFieldQueryLogicalOperator,
|
||||
} from '../../common/custom-fields-query-dropdown/custom-fields-query-dropdown.component'
|
||||
CustomFieldQueryAtom,
|
||||
} from 'src/app/data/custom-field-query'
|
||||
import { CustomFieldQueriesModel } from '../../common/custom-fields-query-dropdown/custom-fields-query-dropdown.component'
|
||||
|
||||
const TEXT_FILTER_TARGET_TITLE = 'title'
|
||||
const TEXT_FILTER_TARGET_TITLE_CONTENT = 'title-content'
|
||||
|
||||
Reference in New Issue
Block a user