Fix supporting filter using table names

This commit is contained in:
Adria Navarro 2024-10-16 12:26:13 +02:00
parent b01564c934
commit 2d460f1955
1 changed files with 53 additions and 1 deletions

View File

@ -15,13 +15,16 @@ import {
ExportRowsResponse, ExportRowsResponse,
FieldType, FieldType,
GetRowResponse, GetRowResponse,
isRelationshipField,
PatchRowRequest, PatchRowRequest,
PatchRowResponse, PatchRowResponse,
Row, Row,
RowAttachment, RowAttachment,
RowSearchParams, RowSearchParams,
SearchFilters,
SearchRowRequest, SearchRowRequest,
SearchRowResponse, SearchRowResponse,
Table,
UserCtx, UserCtx,
ValidateResponse, ValidateResponse,
} from "@budibase/types" } from "@budibase/types"
@ -33,6 +36,8 @@ import sdk from "../../../sdk"
import * as exporters from "../view/exporters" import * as exporters from "../view/exporters"
import { Format } from "../view/exporters" import { Format } from "../view/exporters"
import { apiFileReturn } from "../../../utilities/fileSystem" import { apiFileReturn } from "../../../utilities/fileSystem"
import { dataFilters } from "@budibase/shared-core"
import { isPlainObject } from "lodash"
export * as views from "./views" export * as views from "./views"
@ -211,13 +216,16 @@ export async function search(ctx: Ctx<SearchRowRequest, SearchRowResponse>) {
await context.ensureSnippetContext(true) await context.ensureSnippetContext(true)
const enrichedQuery = await utils.enrichSearchContext( let enrichedQuery: SearchFilters = await utils.enrichSearchContext(
{ ...ctx.request.body.query }, { ...ctx.request.body.query },
{ {
user: sdk.users.getUserContextBindings(ctx.user), user: sdk.users.getUserContextBindings(ctx.user),
} }
) )
const allTables = await sdk.tables.getAllTables()
enrichedQuery = replaceTableNamesInFilters(tableId, enrichedQuery, allTables)
const searchParams: RowSearchParams = { const searchParams: RowSearchParams = {
...ctx.request.body, ...ctx.request.body,
query: enrichedQuery, query: enrichedQuery,
@ -229,6 +237,50 @@ export async function search(ctx: Ctx<SearchRowRequest, SearchRowResponse>) {
ctx.body = await sdk.rows.search(searchParams) ctx.body = await sdk.rows.search(searchParams)
} }
function replaceTableNamesInFilters(
tableId: string,
filters: SearchFilters,
allTables: Table[]
): SearchFilters {
for (const filter of Object.values(filters)) {
if (!isPlainObject(filter)) {
continue
}
for (const key of Object.keys(filter)) {
const matches = key.match(`^(?<relation>.+)\\.(?<field>.+)`)
const relation = matches?.groups?.["relation"]
const field = matches?.groups?.["field"]
if (!relation || !field) {
continue
}
const table = allTables.find(r => r._id === tableId)!
if (Object.values(table.schema).some(f => f.name === relation)) {
continue
}
const matchedTable = allTables.find(t => t.name === relation)
const relationship = Object.values(table.schema).find(
f => isRelationshipField(f) && f.tableId === matchedTable?._id
)
if (!relationship) {
continue
}
const updatedField = `${relationship.name}.${field}`
if (updatedField && updatedField !== key) {
filter[updatedField] = filter[key]
delete filter[key]
}
}
}
return dataFilters.recurseLogicalOperators(filters, (f: SearchFilters) => {
return replaceTableNamesInFilters(tableId, f, allTables)
})
}
export async function validate(ctx: Ctx<Row, ValidateResponse>) { export async function validate(ctx: Ctx<Row, ValidateResponse>) {
const source = await utils.getSource(ctx) const source = await utils.getSource(ctx)
const table = await utils.getTableFromSource(source) const table = await utils.getTableFromSource(source)