diff --git a/packages/server/src/api/routes/tests/viewV2.spec.ts b/packages/server/src/api/routes/tests/viewV2.spec.ts index 7979fac555..7c866e19fe 100644 --- a/packages/server/src/api/routes/tests/viewV2.spec.ts +++ b/packages/server/src/api/routes/tests/viewV2.spec.ts @@ -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> = { name: generator.name(), tableId: table._id!, @@ -178,6 +178,7 @@ describe.each([ visible: true, }, }, + queryUI: {}, id: expect.any(String), version: 2, }) diff --git a/packages/server/src/sdk/app/views/internal.ts b/packages/server/src/sdk/app/views/internal.ts index 96b41bffe8..30e0c18d05 100644 --- a/packages/server/src/sdk/app/views/internal.ts +++ b/packages/server/src/sdk/app/views/internal.ts @@ -4,6 +4,19 @@ import { context, HTTPError } from "@budibase/backend-core" import sdk from "../../../sdk" import * as utils from "../../../db/utils" 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 { const { tableId } = utils.extractViewInfoFromID(viewId) @@ -13,6 +26,7 @@ export async function get(viewId: string): Promise { if (!found) { throw new Error("No view found") } + ensureQueryUISet(found) return found } @@ -24,6 +38,7 @@ export async function getEnriched(viewId: string): Promise { if (!found) { throw new Error("No view found") } + ensureQueryUISet(found) return await enrichSchema(found, table.schema) } diff --git a/packages/shared-core/src/filters.ts b/packages/shared-core/src/filters.ts index 40c70a8a23..64958dd4f7 100644 --- a/packages/shared-core/src/filters.ts +++ b/packages/shared-core/src/filters.ts @@ -572,29 +572,34 @@ export const buildQueryLegacy = ( * * @returns {SearchFilters} */ - -export const buildQuery = ( +export function buildQuery(filter: undefined): undefined +export function buildQuery( + filter: SearchFilterGroup | LegacyFilter[] +): SearchFilters +export function buildQuery( filter?: SearchFilterGroup | LegacyFilter[] -): SearchFilters | undefined => { - const parsedFilter: SearchFilterGroup | undefined = - processSearchFilters(filter) - - if (!parsedFilter) { +): SearchFilters | undefined { + if (!filter) { return } - const operatorMap: { [key in FilterGroupLogicalOperator]: LogicalOperator } = - { - [FilterGroupLogicalOperator.ALL]: LogicalOperator.AND, - [FilterGroupLogicalOperator.ANY]: LogicalOperator.OR, - } + let parsedFilter: SearchFilterGroup + if (Array.isArray(filter)) { + parsedFilter = processSearchFilters(filter) + } else { + parsedFilter = filter + } + + const operatorMap = { + [FilterGroupLogicalOperator.ALL]: LogicalOperator.AND, + [FilterGroupLogicalOperator.ANY]: LogicalOperator.OR, + } const globalOnEmpty = parsedFilter.onEmptyFilter ? parsedFilter.onEmptyFilter : null - const globalOperator: LogicalOperator = - operatorMap[parsedFilter.logicalOperator as FilterGroupLogicalOperator] + const globalOperator = operatorMap[parsedFilter.logicalOperator] return { ...(globalOnEmpty ? { onEmptyFilter: globalOnEmpty } : {}), diff --git a/packages/shared-core/src/utils.ts b/packages/shared-core/src/utils.ts index bead5961f0..7f19371d79 100644 --- a/packages/shared-core/src/utils.ts +++ b/packages/shared-core/src/utils.ts @@ -137,12 +137,8 @@ export function isSupportedUserSearch(query: SearchFilters) { * @param {LegacyFilter[] | SearchFilterGroup} filters */ export const processSearchFilters = ( - filters: LegacyFilter[] | SearchFilterGroup | undefined -): SearchFilterGroup | undefined => { - if (!filters) { - return - } - + filters: LegacyFilter[] +): SearchFilterGroup => { // Base search config. const defaultCfg: SearchFilterGroup = { logicalOperator: FilterGroupLogicalOperator.ALL, @@ -160,65 +156,60 @@ export const processSearchFilters = ( "formulaType", ] - if (Array.isArray(filters)) { - let baseGroup: SearchFilterGroup = { - filters: [], - logicalOperator: FilterGroupLogicalOperator.ALL, - } + let baseGroup: SearchFilterGroup = { + filters: [], + logicalOperator: FilterGroupLogicalOperator.ALL, + } - return filters.reduce((acc: SearchFilterGroup, filter: LegacyFilter) => { - // Sort the properties for easier debugging - const filterPropertyKeys = (Object.keys(filter) as (keyof LegacyFilter)[]) - .sort((a, b) => { - return a.localeCompare(b) - }) - .filter(key => filter[key]) + return filters.reduce((acc: SearchFilterGroup, filter: LegacyFilter) => { + // Sort the properties for easier debugging + const filterPropertyKeys = (Object.keys(filter) as (keyof LegacyFilter)[]) + .sort((a, b) => { + return a.localeCompare(b) + }) + .filter(key => filter[key]) - if (filterPropertyKeys.length == 1) { - const key = filterPropertyKeys[0], - value = filter[key] - // Global - if (key === "onEmptyFilter") { - // unset otherwise - acc.onEmptyFilter = value - } else if (key === "operator" && value === "allOr") { - // Group 1 logical operator - 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] + if (filterPropertyKeys.length == 1) { + const key = filterPropertyKeys[0], + value = filter[key] + // Global + if (key === "onEmptyFilter") { + // unset otherwise + acc.onEmptyFilter = value + } else if (key === "operator" && value === "allOr") { + // Group 1 logical operator + baseGroup.logicalOperator = FilterGroupLogicalOperator.ANY } return acc - }, defaultCfg) - } else if (!filters?.groups) { - return - } - return filters + } + + 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 + }, defaultCfg) }