Merge pull request #14664 from Budibase/fix/view-user-columns

Fix user column searching with logical operators
This commit is contained in:
Michael Drury 2024-09-30 16:39:11 +01:00 committed by GitHub
commit b04af04e3b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 41 additions and 23 deletions

View File

@ -408,7 +408,6 @@ describe.each([
})
})
// We've decided not to try and support binding for in-memory search just now.
!isInMemory &&
describe("bindings", () => {
let globalUsers: any = []
@ -528,6 +527,20 @@ describe.each([
])
})
!isLucene &&
it("should return all rows matching the session user firstname when logical operator used", async () => {
await expectQuery({
$and: {
conditions: [{ equal: { name: "{{ [user].firstName }}" } }],
},
}).toContainExactly([
{
name: config.getUser().firstName,
appointment: future.toISOString(),
},
])
})
it("should parse the date binding and return all rows after the resolved value", async () => {
await tk.withFreeze(serverTime, async () => {
await expectQuery({

View File

@ -11,7 +11,7 @@ import {
RowSearchParams,
} from "@budibase/types"
import { db as dbCore, context } from "@budibase/backend-core"
import { utils } from "@budibase/shared-core"
import { utils, dataFilters } from "@budibase/shared-core"
export async function paginatedSearch(
query: SearchFilters,
@ -31,13 +31,13 @@ export async function fullSearch(
function findColumnInQueries(
column: string,
options: RowSearchParams,
filters: SearchFilters,
callback: (filter: any) => any
) {
if (!options.query) {
if (!filters) {
return
}
for (let filterBlock of Object.values(options.query)) {
for (let filterBlock of Object.values(filters)) {
if (typeof filterBlock !== "object") {
continue
}
@ -49,8 +49,8 @@ function findColumnInQueries(
}
}
function userColumnMapping(column: string, options: RowSearchParams) {
findColumnInQueries(column, options, (filterValue: any): any => {
function userColumnMapping(column: string, filters: SearchFilters) {
findColumnInQueries(column, filters, (filterValue: any): any => {
const isArray = Array.isArray(filterValue),
isString = typeof filterValue === "string"
if (!isString && !isArray) {
@ -83,13 +83,15 @@ function userColumnMapping(column: string, options: RowSearchParams) {
// maps through the search parameters to check if any of the inputs are invalid
// based on the table schema, converts them to something that is valid.
export function searchInputMapping(table: Table, options: RowSearchParams) {
// need an internal function to loop over filters, because this takes the full options
function checkFilters(filters: SearchFilters) {
for (let [key, column] of Object.entries(table.schema || {})) {
switch (column.type) {
case FieldType.BB_REFERENCE_SINGLE: {
const subtype = column.subtype
switch (subtype) {
case BBReferenceFieldSubType.USER:
userColumnMapping(key, options)
userColumnMapping(key, filters)
break
default:
@ -98,11 +100,14 @@ export function searchInputMapping(table: Table, options: RowSearchParams) {
break
}
case FieldType.BB_REFERENCE: {
userColumnMapping(key, options)
userColumnMapping(key, filters)
break
}
}
}
return dataFilters.recurseLogicalOperators(filters, checkFilters)
}
options.query = checkFilters(options.query)
return options
}

View File

@ -124,7 +124,7 @@ export function recurseLogicalOperators(
fn: (f: SearchFilters) => SearchFilters
) {
for (const logical of LOGICAL_OPERATORS) {
if (filters[logical]) {
if (filters?.[logical]) {
filters[logical]!.conditions = filters[logical]!.conditions.map(
condition => fn(condition)
)