This commit is contained in:
Sam Rose 2024-10-16 18:28:40 +01:00
parent dac963a2ff
commit 31c0ed69f1
No known key found for this signature in database
4 changed files with 89 additions and 77 deletions

View File

@ -144,7 +144,7 @@ describe.each([
}) })
}) })
it("can persist views with all fields", async () => { it.only("can persist views with all fields", async () => {
const newView: Required<Omit<CreateViewRequest, "queryUI" | "type">> = { const newView: Required<Omit<CreateViewRequest, "queryUI" | "type">> = {
name: generator.name(), name: generator.name(),
tableId: table._id!, tableId: table._id!,
@ -178,6 +178,7 @@ describe.each([
visible: true, visible: true,
}, },
}, },
queryUI: {},
id: expect.any(String), id: expect.any(String),
version: 2, version: 2,
}) })

View File

@ -4,6 +4,19 @@ import { context, HTTPError } from "@budibase/backend-core"
import sdk from "../../../sdk" import sdk from "../../../sdk"
import * as utils from "../../../db/utils" import * as utils from "../../../db/utils"
import { enrichSchema, isV2 } from "." import { enrichSchema, isV2 } from "."
import { utils as sharedUtils, dataFilters } from "@budibase/shared-core"
function ensureQueryUISet(view: ViewV2) {
if (!view.queryUI && view.query) {
view.queryUI = sharedUtils.processSearchFilters(view.query)
}
}
function ensureQuerySet(view: ViewV2) {
if (!view.query && view.queryUI) {
view.query = dataFilters.buildQuery(view.queryUI)
}
}
export async function get(viewId: string): Promise<ViewV2> { export async function get(viewId: string): Promise<ViewV2> {
const { tableId } = utils.extractViewInfoFromID(viewId) const { tableId } = utils.extractViewInfoFromID(viewId)
@ -13,6 +26,7 @@ export async function get(viewId: string): Promise<ViewV2> {
if (!found) { if (!found) {
throw new Error("No view found") throw new Error("No view found")
} }
ensureQueryUISet(found)
return found return found
} }
@ -24,6 +38,7 @@ export async function getEnriched(viewId: string): Promise<ViewV2Enriched> {
if (!found) { if (!found) {
throw new Error("No view found") throw new Error("No view found")
} }
ensureQueryUISet(found)
return await enrichSchema(found, table.schema) return await enrichSchema(found, table.schema)
} }

View File

@ -572,29 +572,34 @@ export const buildQueryLegacy = (
* *
* @returns {SearchFilters} * @returns {SearchFilters}
*/ */
export function buildQuery(filter: undefined): undefined
export const buildQuery = ( export function buildQuery(
filter: SearchFilterGroup | LegacyFilter[]
): SearchFilters
export function buildQuery(
filter?: SearchFilterGroup | LegacyFilter[] filter?: SearchFilterGroup | LegacyFilter[]
): SearchFilters | undefined => { ): SearchFilters | undefined {
const parsedFilter: SearchFilterGroup | undefined = if (!filter) {
processSearchFilters(filter)
if (!parsedFilter) {
return return
} }
const operatorMap: { [key in FilterGroupLogicalOperator]: LogicalOperator } = let parsedFilter: SearchFilterGroup
{ if (Array.isArray(filter)) {
[FilterGroupLogicalOperator.ALL]: LogicalOperator.AND, parsedFilter = processSearchFilters(filter)
[FilterGroupLogicalOperator.ANY]: LogicalOperator.OR, } else {
} parsedFilter = filter
}
const operatorMap = {
[FilterGroupLogicalOperator.ALL]: LogicalOperator.AND,
[FilterGroupLogicalOperator.ANY]: LogicalOperator.OR,
}
const globalOnEmpty = parsedFilter.onEmptyFilter const globalOnEmpty = parsedFilter.onEmptyFilter
? parsedFilter.onEmptyFilter ? parsedFilter.onEmptyFilter
: null : null
const globalOperator: LogicalOperator = const globalOperator = operatorMap[parsedFilter.logicalOperator]
operatorMap[parsedFilter.logicalOperator as FilterGroupLogicalOperator]
return { return {
...(globalOnEmpty ? { onEmptyFilter: globalOnEmpty } : {}), ...(globalOnEmpty ? { onEmptyFilter: globalOnEmpty } : {}),

View File

@ -137,12 +137,8 @@ export function isSupportedUserSearch(query: SearchFilters) {
* @param {LegacyFilter[] | SearchFilterGroup} filters * @param {LegacyFilter[] | SearchFilterGroup} filters
*/ */
export const processSearchFilters = ( export const processSearchFilters = (
filters: LegacyFilter[] | SearchFilterGroup | undefined filters: LegacyFilter[]
): SearchFilterGroup | undefined => { ): SearchFilterGroup => {
if (!filters) {
return
}
// Base search config. // Base search config.
const defaultCfg: SearchFilterGroup = { const defaultCfg: SearchFilterGroup = {
logicalOperator: FilterGroupLogicalOperator.ALL, logicalOperator: FilterGroupLogicalOperator.ALL,
@ -160,65 +156,60 @@ export const processSearchFilters = (
"formulaType", "formulaType",
] ]
if (Array.isArray(filters)) { let baseGroup: SearchFilterGroup = {
let baseGroup: SearchFilterGroup = { filters: [],
filters: [], logicalOperator: FilterGroupLogicalOperator.ALL,
logicalOperator: FilterGroupLogicalOperator.ALL, }
}
return filters.reduce((acc: SearchFilterGroup, filter: LegacyFilter) => { return filters.reduce((acc: SearchFilterGroup, filter: LegacyFilter) => {
// Sort the properties for easier debugging // Sort the properties for easier debugging
const filterPropertyKeys = (Object.keys(filter) as (keyof LegacyFilter)[]) const filterPropertyKeys = (Object.keys(filter) as (keyof LegacyFilter)[])
.sort((a, b) => { .sort((a, b) => {
return a.localeCompare(b) return a.localeCompare(b)
}) })
.filter(key => filter[key]) .filter(key => filter[key])
if (filterPropertyKeys.length == 1) { if (filterPropertyKeys.length == 1) {
const key = filterPropertyKeys[0], const key = filterPropertyKeys[0],
value = filter[key] value = filter[key]
// Global // Global
if (key === "onEmptyFilter") { if (key === "onEmptyFilter") {
// unset otherwise // unset otherwise
acc.onEmptyFilter = value acc.onEmptyFilter = value
} else if (key === "operator" && value === "allOr") { } else if (key === "operator" && value === "allOr") {
// Group 1 logical operator // Group 1 logical operator
baseGroup.logicalOperator = FilterGroupLogicalOperator.ANY baseGroup.logicalOperator = FilterGroupLogicalOperator.ANY
}
return acc
}
const allowedFilterSettings: AllowedFilters = filterPropertyKeys.reduce(
(acc: AllowedFilters, key) => {
const value = filter[key]
if (filterAllowedKeys.includes(key)) {
if (key === "field") {
acc.push([key, removeKeyNumbering(value)])
} else {
acc.push([key, value])
}
}
return acc
},
[]
)
const migratedFilter: LegacyFilter = Object.fromEntries(
allowedFilterSettings
) as LegacyFilter
baseGroup.filters!.push(migratedFilter)
if (!acc.groups || !acc.groups.length) {
// init the base group
acc.groups = [baseGroup]
} }
return acc return acc
}, defaultCfg) }
} else if (!filters?.groups) {
return const allowedFilterSettings: AllowedFilters = filterPropertyKeys.reduce(
} (acc: AllowedFilters, key) => {
return filters const value = filter[key]
if (filterAllowedKeys.includes(key)) {
if (key === "field") {
acc.push([key, removeKeyNumbering(value)])
} else {
acc.push([key, value])
}
}
return acc
},
[]
)
const migratedFilter: LegacyFilter = Object.fromEntries(
allowedFilterSettings
) as LegacyFilter
baseGroup.filters!.push(migratedFilter)
if (!acc.groups || !acc.groups.length) {
// init the base group
acc.groups = [baseGroup]
}
return acc
}, defaultCfg)
} }