Merge pull request #13507 from Budibase/fix/remove-search-query
Search type updates
This commit is contained in:
commit
fd53336245
|
@ -17,8 +17,8 @@ import {
|
|||
ContextUser,
|
||||
CouchFindOptions,
|
||||
DatabaseQueryOpts,
|
||||
SearchQuery,
|
||||
SearchQueryOperators,
|
||||
SearchFilters,
|
||||
SearchFilterOperator,
|
||||
SearchUsersRequest,
|
||||
User,
|
||||
} from "@budibase/types"
|
||||
|
@ -44,11 +44,11 @@ function removeUserPassword(users: User | User[]) {
|
|||
return users
|
||||
}
|
||||
|
||||
export function isSupportedUserSearch(query: SearchQuery) {
|
||||
export function isSupportedUserSearch(query: SearchFilters) {
|
||||
const allowed = [
|
||||
{ op: SearchQueryOperators.STRING, key: "email" },
|
||||
{ op: SearchQueryOperators.EQUAL, key: "_id" },
|
||||
{ op: SearchQueryOperators.ONE_OF, key: "_id" },
|
||||
{ op: SearchFilterOperator.STRING, key: "email" },
|
||||
{ op: SearchFilterOperator.EQUAL, key: "_id" },
|
||||
{ op: SearchFilterOperator.ONE_OF, key: "_id" },
|
||||
]
|
||||
for (let [key, operation] of Object.entries(query)) {
|
||||
if (typeof operation !== "object") {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
Label,
|
||||
Multiselect,
|
||||
} from "@budibase/bbui"
|
||||
import { FieldType, SearchQueryOperators } from "@budibase/types"
|
||||
import { FieldType, SearchFilterOperator } from "@budibase/types"
|
||||
import { generate } from "shortid"
|
||||
import { LuceneUtils, Constants } from "@budibase/frontend-core"
|
||||
import { getContext } from "svelte"
|
||||
|
@ -247,7 +247,7 @@
|
|||
<slot name="binding" {filter} />
|
||||
{:else if [FieldType.STRING, FieldType.LONGFORM, FieldType.NUMBER, FieldType.BIGINT, FieldType.FORMULA].includes(filter.type)}
|
||||
<Input disabled={filter.noValue} bind:value={filter.value} />
|
||||
{:else if filter.type === FieldType.ARRAY || (filter.type === FieldType.OPTIONS && filter.operator === SearchQueryOperators.ONE_OF)}
|
||||
{:else if filter.type === FieldType.ARRAY || (filter.type === FieldType.OPTIONS && filter.operator === SearchFilterOperator.ONE_OF)}
|
||||
<Multiselect
|
||||
disabled={filter.noValue}
|
||||
options={getFieldOptions(filter.field)}
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
PermissionLevel,
|
||||
QuotaUsageType,
|
||||
SaveTableRequest,
|
||||
SearchQueryOperators,
|
||||
SearchFilterOperator,
|
||||
SortOrder,
|
||||
SortType,
|
||||
StaticQuotaName,
|
||||
|
@ -132,7 +132,7 @@ describe.each([
|
|||
primaryDisplay: generator.word(),
|
||||
query: [
|
||||
{
|
||||
operator: SearchQueryOperators.EQUAL,
|
||||
operator: SearchFilterOperator.EQUAL,
|
||||
field: "field",
|
||||
value: "value",
|
||||
},
|
||||
|
@ -236,7 +236,7 @@ describe.each([
|
|||
...view,
|
||||
query: [
|
||||
{
|
||||
operator: SearchQueryOperators.EQUAL,
|
||||
operator: SearchFilterOperator.EQUAL,
|
||||
field: "newField",
|
||||
value: "thatValue",
|
||||
},
|
||||
|
@ -263,7 +263,7 @@ describe.each([
|
|||
primaryDisplay: generator.word(),
|
||||
query: [
|
||||
{
|
||||
operator: SearchQueryOperators.EQUAL,
|
||||
operator: SearchFilterOperator.EQUAL,
|
||||
field: generator.word(),
|
||||
value: generator.word(),
|
||||
},
|
||||
|
@ -341,7 +341,7 @@ describe.each([
|
|||
tableId: generator.guid(),
|
||||
query: [
|
||||
{
|
||||
operator: SearchQueryOperators.EQUAL,
|
||||
operator: SearchFilterOperator.EQUAL,
|
||||
field: "newField",
|
||||
value: "thatValue",
|
||||
},
|
||||
|
@ -671,7 +671,7 @@ describe.each([
|
|||
name: generator.guid(),
|
||||
query: [
|
||||
{
|
||||
operator: SearchQueryOperators.EQUAL,
|
||||
operator: SearchFilterOperator.EQUAL,
|
||||
field: "two",
|
||||
value: "bar2",
|
||||
},
|
||||
|
|
|
@ -160,7 +160,7 @@ describe("internal search", () => {
|
|||
const response = await search.paginatedSearch(
|
||||
{
|
||||
contains: {
|
||||
column: "a",
|
||||
column: ["a"],
|
||||
colArr: [1, 2, 3],
|
||||
},
|
||||
},
|
||||
|
@ -168,7 +168,7 @@ describe("internal search", () => {
|
|||
)
|
||||
checkLucene(
|
||||
response,
|
||||
`(*:* AND column:a AND colArr:(1 AND 2 AND 3))`,
|
||||
`(*:* AND column:(a) AND colArr:(1 AND 2 AND 3))`,
|
||||
PARAMS
|
||||
)
|
||||
})
|
|
@ -4,9 +4,9 @@ import {
|
|||
FieldType,
|
||||
FormulaType,
|
||||
SearchFilter,
|
||||
SearchQuery,
|
||||
SearchFilters,
|
||||
SearchQueryFields,
|
||||
SearchQueryOperators,
|
||||
SearchFilterOperator,
|
||||
SortDirection,
|
||||
SortType,
|
||||
} from "@budibase/types"
|
||||
|
@ -99,18 +99,19 @@ export const NoEmptyFilterStrings = [
|
|||
* Removes any fields that contain empty strings that would cause inconsistent
|
||||
* behaviour with how backend tables are filtered (no value means no filter).
|
||||
*/
|
||||
const cleanupQuery = (query: SearchQuery) => {
|
||||
const cleanupQuery = (query: SearchFilters) => {
|
||||
if (!query) {
|
||||
return query
|
||||
}
|
||||
for (let filterField of NoEmptyFilterStrings) {
|
||||
if (!query[filterField]) {
|
||||
const operator = filterField as SearchFilterOperator
|
||||
if (!query[operator]) {
|
||||
continue
|
||||
}
|
||||
|
||||
for (let [key, value] of Object.entries(query[filterField]!)) {
|
||||
for (let [key, value] of Object.entries(query[operator]!)) {
|
||||
if (value == null || value === "") {
|
||||
delete query[filterField]![key]
|
||||
delete query[operator]![key]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -136,7 +137,7 @@ export const removeKeyNumbering = (key: string): string => {
|
|||
* @param filter the builder filter structure
|
||||
*/
|
||||
export const buildLuceneQuery = (filter: SearchFilter[]) => {
|
||||
let query: SearchQuery = {
|
||||
let query: SearchFilters = {
|
||||
string: {},
|
||||
fuzzy: {},
|
||||
range: {},
|
||||
|
@ -157,6 +158,7 @@ export const buildLuceneQuery = (filter: SearchFilter[]) => {
|
|||
filter.forEach(expression => {
|
||||
let { operator, field, type, value, externalType, onEmptyFilter } =
|
||||
expression
|
||||
const queryOperator = operator as SearchFilterOperator
|
||||
const isHbs =
|
||||
typeof value === "string" && (value.match(HBS_REGEX) || []).length > 0
|
||||
// Parse all values into correct types
|
||||
|
@ -171,8 +173,8 @@ export const buildLuceneQuery = (filter: SearchFilter[]) => {
|
|||
if (
|
||||
type === "datetime" &&
|
||||
!isHbs &&
|
||||
operator !== "empty" &&
|
||||
operator !== "notEmpty"
|
||||
queryOperator !== "empty" &&
|
||||
queryOperator !== "notEmpty"
|
||||
) {
|
||||
// Ensure date value is a valid date and parse into correct format
|
||||
if (!value) {
|
||||
|
@ -185,7 +187,7 @@ export const buildLuceneQuery = (filter: SearchFilter[]) => {
|
|||
}
|
||||
}
|
||||
if (type === "number" && typeof value === "string" && !isHbs) {
|
||||
if (operator === "oneOf") {
|
||||
if (queryOperator === "oneOf") {
|
||||
value = value.split(",").map(item => parseFloat(item))
|
||||
} else {
|
||||
value = parseFloat(value)
|
||||
|
@ -225,24 +227,24 @@ export const buildLuceneQuery = (filter: SearchFilter[]) => {
|
|||
) {
|
||||
query.range[field].high = value
|
||||
}
|
||||
} else if (query[operator] && operator !== "onEmptyFilter") {
|
||||
} else if (query[queryOperator] && operator !== "onEmptyFilter") {
|
||||
if (type === "boolean") {
|
||||
// Transform boolean filters to cope with null.
|
||||
// "equals false" needs to be "not equals true"
|
||||
// "not equals false" needs to be "equals true"
|
||||
if (operator === "equal" && value === false) {
|
||||
if (queryOperator === "equal" && value === false) {
|
||||
query.notEqual = query.notEqual || {}
|
||||
query.notEqual[field] = true
|
||||
} else if (operator === "notEqual" && value === false) {
|
||||
} else if (queryOperator === "notEqual" && value === false) {
|
||||
query.equal = query.equal || {}
|
||||
query.equal[field] = true
|
||||
} else {
|
||||
query[operator] = query[operator] || {}
|
||||
query[operator]![field] = value
|
||||
query[queryOperator] = query[queryOperator] || {}
|
||||
query[queryOperator]![field] = value
|
||||
}
|
||||
} else {
|
||||
query[operator] = query[operator] || {}
|
||||
query[operator]![field] = value
|
||||
query[queryOperator] = query[queryOperator] || {}
|
||||
query[queryOperator]![field] = value
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -255,7 +257,7 @@ export const buildLuceneQuery = (filter: SearchFilter[]) => {
|
|||
* @param docs the data
|
||||
* @param query the JSON lucene query
|
||||
*/
|
||||
export const runLuceneQuery = (docs: any[], query?: SearchQuery) => {
|
||||
export const runLuceneQuery = (docs: any[], query?: SearchFilters) => {
|
||||
if (!docs || !Array.isArray(docs)) {
|
||||
return []
|
||||
}
|
||||
|
@ -269,7 +271,7 @@ export const runLuceneQuery = (docs: any[], query?: SearchQuery) => {
|
|||
// Iterates over a set of filters and evaluates a fail function against a doc
|
||||
const match =
|
||||
(
|
||||
type: keyof SearchQueryFields,
|
||||
type: SearchFilterOperator,
|
||||
failFn: (docValue: any, testValue: any) => boolean
|
||||
) =>
|
||||
(doc: any) => {
|
||||
|
@ -286,7 +288,7 @@ export const runLuceneQuery = (docs: any[], query?: SearchQuery) => {
|
|||
|
||||
// Process a string match (fails if the value does not start with the string)
|
||||
const stringMatch = match(
|
||||
SearchQueryOperators.STRING,
|
||||
SearchFilterOperator.STRING,
|
||||
(docValue: string, testValue: string) => {
|
||||
return (
|
||||
!docValue ||
|
||||
|
@ -297,7 +299,7 @@ export const runLuceneQuery = (docs: any[], query?: SearchQuery) => {
|
|||
|
||||
// Process a fuzzy match (treat the same as starts with when running locally)
|
||||
const fuzzyMatch = match(
|
||||
SearchQueryOperators.FUZZY,
|
||||
SearchFilterOperator.FUZZY,
|
||||
(docValue: string, testValue: string) => {
|
||||
return (
|
||||
!docValue ||
|
||||
|
@ -308,7 +310,7 @@ export const runLuceneQuery = (docs: any[], query?: SearchQuery) => {
|
|||
|
||||
// Process a range match
|
||||
const rangeMatch = match(
|
||||
SearchQueryOperators.RANGE,
|
||||
SearchFilterOperator.RANGE,
|
||||
(
|
||||
docValue: string | number | null,
|
||||
testValue: { low: number; high: number }
|
||||
|
@ -331,7 +333,7 @@ export const runLuceneQuery = (docs: any[], query?: SearchQuery) => {
|
|||
|
||||
// Process an equal match (fails if the value is different)
|
||||
const equalMatch = match(
|
||||
SearchQueryOperators.EQUAL,
|
||||
SearchFilterOperator.EQUAL,
|
||||
(docValue: any, testValue: string | null) => {
|
||||
return testValue != null && testValue !== "" && docValue !== testValue
|
||||
}
|
||||
|
@ -339,7 +341,7 @@ export const runLuceneQuery = (docs: any[], query?: SearchQuery) => {
|
|||
|
||||
// Process a not-equal match (fails if the value is the same)
|
||||
const notEqualMatch = match(
|
||||
SearchQueryOperators.NOT_EQUAL,
|
||||
SearchFilterOperator.NOT_EQUAL,
|
||||
(docValue: any, testValue: string | null) => {
|
||||
return testValue != null && testValue !== "" && docValue === testValue
|
||||
}
|
||||
|
@ -347,7 +349,7 @@ export const runLuceneQuery = (docs: any[], query?: SearchQuery) => {
|
|||
|
||||
// Process an empty match (fails if the value is not empty)
|
||||
const emptyMatch = match(
|
||||
SearchQueryOperators.EMPTY,
|
||||
SearchFilterOperator.EMPTY,
|
||||
(docValue: string | null) => {
|
||||
return docValue != null && docValue !== ""
|
||||
}
|
||||
|
@ -355,7 +357,7 @@ export const runLuceneQuery = (docs: any[], query?: SearchQuery) => {
|
|||
|
||||
// Process a not-empty match (fails is the value is empty)
|
||||
const notEmptyMatch = match(
|
||||
SearchQueryOperators.NOT_EMPTY,
|
||||
SearchFilterOperator.NOT_EMPTY,
|
||||
(docValue: string | null) => {
|
||||
return docValue == null || docValue === ""
|
||||
}
|
||||
|
@ -363,7 +365,7 @@ export const runLuceneQuery = (docs: any[], query?: SearchQuery) => {
|
|||
|
||||
// Process an includes match (fails if the value is not included)
|
||||
const oneOf = match(
|
||||
SearchQueryOperators.ONE_OF,
|
||||
SearchFilterOperator.ONE_OF,
|
||||
(docValue: any, testValue: any) => {
|
||||
if (typeof testValue === "string") {
|
||||
testValue = testValue.split(",")
|
||||
|
@ -376,28 +378,28 @@ export const runLuceneQuery = (docs: any[], query?: SearchQuery) => {
|
|||
)
|
||||
|
||||
const containsAny = match(
|
||||
SearchQueryOperators.CONTAINS_ANY,
|
||||
SearchFilterOperator.CONTAINS_ANY,
|
||||
(docValue: any, testValue: any) => {
|
||||
return !docValue?.includes(...testValue)
|
||||
}
|
||||
)
|
||||
|
||||
const contains = match(
|
||||
SearchQueryOperators.CONTAINS,
|
||||
SearchFilterOperator.CONTAINS,
|
||||
(docValue: string | any[], testValue: any[]) => {
|
||||
return !testValue?.every((item: any) => docValue?.includes(item))
|
||||
}
|
||||
)
|
||||
|
||||
const notContains = match(
|
||||
SearchQueryOperators.NOT_CONTAINS,
|
||||
SearchFilterOperator.NOT_CONTAINS,
|
||||
(docValue: string | any[], testValue: any[]) => {
|
||||
return testValue?.every((item: any) => docValue?.includes(item))
|
||||
}
|
||||
)
|
||||
|
||||
const docMatch = (doc: any) => {
|
||||
const filterFunctions: Record<SearchQueryOperators, (doc: any) => boolean> =
|
||||
const filterFunctions: Record<SearchFilterOperator, (doc: any) => boolean> =
|
||||
{
|
||||
string: stringMatch,
|
||||
fuzzy: fuzzyMatch,
|
||||
|
@ -412,7 +414,7 @@ export const runLuceneQuery = (docs: any[], query?: SearchQuery) => {
|
|||
notContains: notContains,
|
||||
}
|
||||
|
||||
const activeFilterKeys: SearchQueryOperators[] = Object.entries(query || {})
|
||||
const activeFilterKeys: SearchFilterOperator[] = Object.entries(query || {})
|
||||
.filter(
|
||||
([key, value]: [string, any]) =>
|
||||
!["allOr", "onEmptyFilter"].includes(key) &&
|
||||
|
@ -480,7 +482,7 @@ export const luceneLimit = (docs: any[], limit: string) => {
|
|||
return docs.slice(0, numLimit)
|
||||
}
|
||||
|
||||
export const hasFilters = (query?: SearchQuery) => {
|
||||
export const hasFilters = (query?: SearchFilters) => {
|
||||
if (!query) {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {
|
||||
SearchQuery,
|
||||
SearchQueryOperators,
|
||||
SearchFilters,
|
||||
SearchFilterOperator,
|
||||
FieldType,
|
||||
SearchFilter,
|
||||
} from "@budibase/types"
|
||||
|
@ -46,8 +46,8 @@ describe("runLuceneQuery", () => {
|
|||
},
|
||||
]
|
||||
|
||||
function buildQuery(filters: { [filterKey: string]: any }): SearchQuery {
|
||||
const query: SearchQuery = {
|
||||
function buildQuery(filters: { [filterKey: string]: any }): SearchFilters {
|
||||
const query: SearchFilters = {
|
||||
string: {},
|
||||
fuzzy: {},
|
||||
range: {},
|
||||
|
@ -63,7 +63,7 @@ describe("runLuceneQuery", () => {
|
|||
}
|
||||
|
||||
for (const filterKey in filters) {
|
||||
query[filterKey as SearchQueryOperators] = filters[filterKey]
|
||||
query[filterKey as SearchFilterOperator] = filters[filterKey]
|
||||
}
|
||||
|
||||
return query
|
||||
|
@ -265,13 +265,13 @@ describe("buildLuceneQuery", () => {
|
|||
it("should parseFloat if the type is a number, but the value is a numeric string", () => {
|
||||
const filter: SearchFilter[] = [
|
||||
{
|
||||
operator: SearchQueryOperators.EQUAL,
|
||||
operator: SearchFilterOperator.EQUAL,
|
||||
field: "customer_id",
|
||||
type: FieldType.NUMBER,
|
||||
value: "1212",
|
||||
},
|
||||
{
|
||||
operator: SearchQueryOperators.ONE_OF,
|
||||
operator: SearchFilterOperator.ONE_OF,
|
||||
field: "customer_id",
|
||||
type: FieldType.NUMBER,
|
||||
value: "1000,1212,3400",
|
||||
|
@ -299,13 +299,13 @@ describe("buildLuceneQuery", () => {
|
|||
it("should not parseFloat if the type is a number, but the value is a handlebars binding string", () => {
|
||||
const filter: SearchFilter[] = [
|
||||
{
|
||||
operator: SearchQueryOperators.EQUAL,
|
||||
operator: SearchFilterOperator.EQUAL,
|
||||
field: "customer_id",
|
||||
type: FieldType.NUMBER,
|
||||
value: "{{ customer_id }}",
|
||||
},
|
||||
{
|
||||
operator: SearchQueryOperators.ONE_OF,
|
||||
operator: SearchFilterOperator.ONE_OF,
|
||||
field: "customer_id",
|
||||
type: FieldType.NUMBER,
|
||||
value: "{{ list_of_customer_ids }}",
|
||||
|
@ -333,19 +333,19 @@ describe("buildLuceneQuery", () => {
|
|||
it("should cast string to boolean if the type is boolean", () => {
|
||||
const filter: SearchFilter[] = [
|
||||
{
|
||||
operator: SearchQueryOperators.EQUAL,
|
||||
operator: SearchFilterOperator.EQUAL,
|
||||
field: "a",
|
||||
type: FieldType.BOOLEAN,
|
||||
value: "not_true",
|
||||
},
|
||||
{
|
||||
operator: SearchQueryOperators.NOT_EQUAL,
|
||||
operator: SearchFilterOperator.NOT_EQUAL,
|
||||
field: "b",
|
||||
type: FieldType.BOOLEAN,
|
||||
value: "not_true",
|
||||
},
|
||||
{
|
||||
operator: SearchQueryOperators.EQUAL,
|
||||
operator: SearchFilterOperator.EQUAL,
|
||||
field: "c",
|
||||
type: FieldType.BOOLEAN,
|
||||
value: "true",
|
||||
|
@ -374,19 +374,19 @@ describe("buildLuceneQuery", () => {
|
|||
it("should split the string for contains operators", () => {
|
||||
const filter: SearchFilter[] = [
|
||||
{
|
||||
operator: SearchQueryOperators.CONTAINS,
|
||||
operator: SearchFilterOperator.CONTAINS,
|
||||
field: "description",
|
||||
type: FieldType.ARRAY,
|
||||
value: "Large box,Heavy box,Small box",
|
||||
},
|
||||
{
|
||||
operator: SearchQueryOperators.NOT_CONTAINS,
|
||||
operator: SearchFilterOperator.NOT_CONTAINS,
|
||||
field: "description",
|
||||
type: FieldType.ARRAY,
|
||||
value: "Large box,Heavy box,Small box",
|
||||
},
|
||||
{
|
||||
operator: SearchQueryOperators.CONTAINS_ANY,
|
||||
operator: SearchFilterOperator.CONTAINS_ANY,
|
||||
field: "description",
|
||||
type: FieldType.ARRAY,
|
||||
value: "Large box,Heavy box,Small box",
|
||||
|
|
|
@ -1,68 +1,11 @@
|
|||
import { FieldType } from "../../documents"
|
||||
import { EmptyFilterOption } from "../../sdk"
|
||||
import { EmptyFilterOption, SearchFilters } from "../../sdk"
|
||||
|
||||
export type SearchFilter = {
|
||||
operator: keyof SearchQuery
|
||||
operator: keyof SearchFilters | "rangeLow" | "rangeHigh"
|
||||
onEmptyFilter?: EmptyFilterOption
|
||||
field: string
|
||||
type?: FieldType
|
||||
value: any
|
||||
externalType?: string
|
||||
}
|
||||
|
||||
export enum SearchQueryOperators {
|
||||
STRING = "string",
|
||||
FUZZY = "fuzzy",
|
||||
RANGE = "range",
|
||||
EQUAL = "equal",
|
||||
NOT_EQUAL = "notEqual",
|
||||
EMPTY = "empty",
|
||||
NOT_EMPTY = "notEmpty",
|
||||
ONE_OF = "oneOf",
|
||||
CONTAINS = "contains",
|
||||
NOT_CONTAINS = "notContains",
|
||||
CONTAINS_ANY = "containsAny",
|
||||
}
|
||||
|
||||
export type SearchQuery = {
|
||||
allOr?: boolean
|
||||
onEmptyFilter?: EmptyFilterOption
|
||||
[SearchQueryOperators.STRING]?: {
|
||||
[key: string]: string
|
||||
}
|
||||
[SearchQueryOperators.FUZZY]?: {
|
||||
[key: string]: string
|
||||
}
|
||||
[SearchQueryOperators.RANGE]?: {
|
||||
[key: string]: {
|
||||
high: number | string
|
||||
low: number | string
|
||||
}
|
||||
}
|
||||
[SearchQueryOperators.EQUAL]?: {
|
||||
[key: string]: any
|
||||
}
|
||||
[SearchQueryOperators.NOT_EQUAL]?: {
|
||||
[key: string]: any
|
||||
}
|
||||
[SearchQueryOperators.EMPTY]?: {
|
||||
[key: string]: any
|
||||
}
|
||||
[SearchQueryOperators.NOT_EMPTY]?: {
|
||||
[key: string]: any
|
||||
}
|
||||
[SearchQueryOperators.ONE_OF]?: {
|
||||
[key: string]: any[]
|
||||
}
|
||||
[SearchQueryOperators.CONTAINS]?: {
|
||||
[key: string]: any[]
|
||||
}
|
||||
[SearchQueryOperators.NOT_CONTAINS]?: {
|
||||
[key: string]: any[]
|
||||
}
|
||||
[SearchQueryOperators.CONTAINS_ANY]?: {
|
||||
[key: string]: any[]
|
||||
}
|
||||
}
|
||||
|
||||
export type SearchQueryFields = Omit<SearchQuery, "allOr" | "onEmptyFilter">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { User } from "../../documents"
|
||||
import { SearchQuery } from "./searchFilter"
|
||||
import { SearchFilters } from "../../sdk"
|
||||
|
||||
export interface SaveUserResponse {
|
||||
_id: string
|
||||
|
@ -55,7 +55,7 @@ export interface InviteUsersResponse {
|
|||
|
||||
export interface SearchUsersRequest {
|
||||
bookmark?: string
|
||||
query?: SearchQuery
|
||||
query?: SearchFilters
|
||||
appId?: string
|
||||
limit?: number
|
||||
paginate?: boolean
|
||||
|
|
|
@ -3,47 +3,63 @@ import { Row, Table } from "../documents"
|
|||
import { SortType } from "../api"
|
||||
import { Knex } from "knex"
|
||||
|
||||
export enum SearchFilterOperator {
|
||||
STRING = "string",
|
||||
FUZZY = "fuzzy",
|
||||
RANGE = "range",
|
||||
EQUAL = "equal",
|
||||
NOT_EQUAL = "notEqual",
|
||||
EMPTY = "empty",
|
||||
NOT_EMPTY = "notEmpty",
|
||||
ONE_OF = "oneOf",
|
||||
CONTAINS = "contains",
|
||||
NOT_CONTAINS = "notContains",
|
||||
CONTAINS_ANY = "containsAny",
|
||||
}
|
||||
|
||||
export interface SearchFilters {
|
||||
allOr?: boolean
|
||||
onEmptyFilter?: EmptyFilterOption
|
||||
string?: {
|
||||
[SearchFilterOperator.STRING]?: {
|
||||
[key: string]: string
|
||||
}
|
||||
fuzzy?: {
|
||||
[SearchFilterOperator.FUZZY]?: {
|
||||
[key: string]: string
|
||||
}
|
||||
range?: {
|
||||
[SearchFilterOperator.RANGE]?: {
|
||||
[key: string]: {
|
||||
high: number | string
|
||||
low: number | string
|
||||
}
|
||||
}
|
||||
equal?: {
|
||||
[SearchFilterOperator.EQUAL]?: {
|
||||
[key: string]: any
|
||||
}
|
||||
notEqual?: {
|
||||
[SearchFilterOperator.NOT_EQUAL]?: {
|
||||
[key: string]: any
|
||||
}
|
||||
empty?: {
|
||||
[SearchFilterOperator.EMPTY]?: {
|
||||
[key: string]: any
|
||||
}
|
||||
notEmpty?: {
|
||||
[SearchFilterOperator.NOT_EMPTY]?: {
|
||||
[key: string]: any
|
||||
}
|
||||
oneOf?: {
|
||||
[SearchFilterOperator.ONE_OF]?: {
|
||||
[key: string]: any[]
|
||||
}
|
||||
contains?: {
|
||||
[key: string]: any[] | any
|
||||
}
|
||||
notContains?: {
|
||||
[SearchFilterOperator.CONTAINS]?: {
|
||||
[key: string]: any[]
|
||||
}
|
||||
containsAny?: {
|
||||
[SearchFilterOperator.NOT_CONTAINS]?: {
|
||||
[key: string]: any[]
|
||||
}
|
||||
[SearchFilterOperator.CONTAINS_ANY]?: {
|
||||
[key: string]: any[]
|
||||
}
|
||||
}
|
||||
|
||||
export type SearchQueryFields = Omit<SearchFilters, "allOr" | "onEmptyFilter">
|
||||
|
||||
export interface SortJson {
|
||||
[key: string]: {
|
||||
direction: SortDirection
|
||||
|
|
|
@ -4,7 +4,7 @@ import {
|
|||
InviteUsersRequest,
|
||||
User,
|
||||
CreateAdminUserRequest,
|
||||
SearchQuery,
|
||||
SearchFilters,
|
||||
InviteUsersResponse,
|
||||
} from "@budibase/types"
|
||||
import structures from "../structures"
|
||||
|
@ -150,7 +150,7 @@ export class UserAPI extends TestAPI {
|
|||
}
|
||||
|
||||
searchUsers = (
|
||||
{ query }: { query?: SearchQuery },
|
||||
{ query }: { query?: SearchFilters },
|
||||
opts?: { status?: number; noHeaders?: boolean }
|
||||
) => {
|
||||
const req = this.request
|
||||
|
|
Loading…
Reference in New Issue