Merge pull request #15852 from Budibase/feature/view-calculations-static-formulas

Allow numeric static formulas to be used in view calculations
This commit is contained in:
Michael Drury 2025-04-01 11:59:33 +01:00 committed by GitHub
commit 74faf3e433
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 72 additions and 3 deletions

View File

@ -6,7 +6,13 @@
Multiselect,
Button,
} from "@budibase/bbui"
import { CalculationType, canGroupBy, isNumeric } from "@budibase/types"
import {
CalculationType,
canGroupBy,
FieldType,
isNumeric,
isNumericStaticFormula,
} from "@budibase/types"
import InfoDisplay from "@/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/InfoDisplay.svelte"
import { getContext } from "svelte"
import DetailPopover from "@/components/common/DetailPopover.svelte"
@ -94,10 +100,15 @@
if (fieldSchema.calculationType) {
return false
}
// static numeric formulas will work
if (isNumericStaticFormula(fieldSchema)) {
return true
}
// Only allow numeric columns for most calculation types
if (
self.type !== CalculationType.COUNT &&
!isNumeric(fieldSchema.type)
!isNumeric(fieldSchema.type) &&
fieldSchema.responseType !== FieldType.NUMBER
) {
return false
}

View File

@ -35,6 +35,7 @@ import {
ViewV2,
ViewV2Schema,
ViewV2Type,
FormulaType,
} from "@budibase/types"
import { generator, mocks } from "@budibase/backend-core/tests"
import { datasourceDescribe } from "../../../integrations/tests/utils"
@ -3865,6 +3866,48 @@ if (descriptions.length) {
expect(rows[0].count).toEqual(2)
})
isInternal &&
it("should be able to max a static formula field", async () => {
const table = await config.api.table.save(
saveTableRequest({
schema: {
string: {
type: FieldType.STRING,
name: "string",
},
formula: {
type: FieldType.FORMULA,
name: "formula",
formulaType: FormulaType.STATIC,
responseType: FieldType.NUMBER,
formula: "{{ string }}",
},
},
})
)
await config.api.row.save(table._id!, {
string: "1",
})
await config.api.row.save(table._id!, {
string: "2",
})
const view = await config.api.viewV2.create({
tableId: table._id!,
name: generator.guid(),
type: ViewV2Type.CALCULATION,
schema: {
maxFormula: {
visible: true,
calculationType: CalculationType.MAX,
field: "formula",
},
},
})
const { rows } = await config.api.row.search(view.id)
expect(rows.length).toEqual(1)
expect(rows[0].maxFormula).toEqual(2)
})
it("should not be able to COUNT(DISTINCT ...) against a non-existent field", async () => {
await config.api.viewV2.create(
{

View File

@ -4,6 +4,7 @@ import {
canGroupBy,
FieldType,
isNumeric,
isNumericStaticFormula,
PermissionLevel,
RelationSchemaField,
RenameColumn,
@ -176,7 +177,11 @@ async function guardCalculationViewSchema(
}
const isCount = schema.calculationType === CalculationType.COUNT
if (!isCount && !isNumeric(targetSchema.type)) {
if (
!isCount &&
!isNumeric(targetSchema.type) &&
!isNumericStaticFormula(targetSchema)
) {
throw new HTTPError(
`Calculation field "${name}" references field "${schema.field}" which is not a numeric field`,
400

View File

@ -1,4 +1,5 @@
import { Document } from "../document"
import { FieldSchema, FormulaType } from "./table"
export enum FieldType {
/**
@ -147,6 +148,15 @@ export function isNumeric(type: FieldType) {
return NumericTypes.includes(type)
}
export function isNumericStaticFormula(schema: FieldSchema) {
return (
schema.type === FieldType.FORMULA &&
schema.formulaType === FormulaType.STATIC &&
schema.responseType &&
isNumeric(schema.responseType)
)
}
export const GroupByTypes = [
FieldType.STRING,
FieldType.LONGFORM,