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:
commit
74faf3e433
|
@ -6,7 +6,13 @@
|
||||||
Multiselect,
|
Multiselect,
|
||||||
Button,
|
Button,
|
||||||
} from "@budibase/bbui"
|
} 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 InfoDisplay from "@/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/InfoDisplay.svelte"
|
||||||
import { getContext } from "svelte"
|
import { getContext } from "svelte"
|
||||||
import DetailPopover from "@/components/common/DetailPopover.svelte"
|
import DetailPopover from "@/components/common/DetailPopover.svelte"
|
||||||
|
@ -94,10 +100,15 @@
|
||||||
if (fieldSchema.calculationType) {
|
if (fieldSchema.calculationType) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
// static numeric formulas will work
|
||||||
|
if (isNumericStaticFormula(fieldSchema)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
// Only allow numeric columns for most calculation types
|
// Only allow numeric columns for most calculation types
|
||||||
if (
|
if (
|
||||||
self.type !== CalculationType.COUNT &&
|
self.type !== CalculationType.COUNT &&
|
||||||
!isNumeric(fieldSchema.type)
|
!isNumeric(fieldSchema.type) &&
|
||||||
|
fieldSchema.responseType !== FieldType.NUMBER
|
||||||
) {
|
) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ import {
|
||||||
ViewV2,
|
ViewV2,
|
||||||
ViewV2Schema,
|
ViewV2Schema,
|
||||||
ViewV2Type,
|
ViewV2Type,
|
||||||
|
FormulaType,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import { generator, mocks } from "@budibase/backend-core/tests"
|
import { generator, mocks } from "@budibase/backend-core/tests"
|
||||||
import { datasourceDescribe } from "../../../integrations/tests/utils"
|
import { datasourceDescribe } from "../../../integrations/tests/utils"
|
||||||
|
@ -3865,6 +3866,48 @@ if (descriptions.length) {
|
||||||
expect(rows[0].count).toEqual(2)
|
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 () => {
|
it("should not be able to COUNT(DISTINCT ...) against a non-existent field", async () => {
|
||||||
await config.api.viewV2.create(
|
await config.api.viewV2.create(
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,6 +4,7 @@ import {
|
||||||
canGroupBy,
|
canGroupBy,
|
||||||
FieldType,
|
FieldType,
|
||||||
isNumeric,
|
isNumeric,
|
||||||
|
isNumericStaticFormula,
|
||||||
PermissionLevel,
|
PermissionLevel,
|
||||||
RelationSchemaField,
|
RelationSchemaField,
|
||||||
RenameColumn,
|
RenameColumn,
|
||||||
|
@ -176,7 +177,11 @@ async function guardCalculationViewSchema(
|
||||||
}
|
}
|
||||||
|
|
||||||
const isCount = schema.calculationType === CalculationType.COUNT
|
const isCount = schema.calculationType === CalculationType.COUNT
|
||||||
if (!isCount && !isNumeric(targetSchema.type)) {
|
if (
|
||||||
|
!isCount &&
|
||||||
|
!isNumeric(targetSchema.type) &&
|
||||||
|
!isNumericStaticFormula(targetSchema)
|
||||||
|
) {
|
||||||
throw new HTTPError(
|
throw new HTTPError(
|
||||||
`Calculation field "${name}" references field "${schema.field}" which is not a numeric field`,
|
`Calculation field "${name}" references field "${schema.field}" which is not a numeric field`,
|
||||||
400
|
400
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { Document } from "../document"
|
import { Document } from "../document"
|
||||||
|
import { FieldSchema, FormulaType } from "./table"
|
||||||
|
|
||||||
export enum FieldType {
|
export enum FieldType {
|
||||||
/**
|
/**
|
||||||
|
@ -147,6 +148,15 @@ export function isNumeric(type: FieldType) {
|
||||||
return NumericTypes.includes(type)
|
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 = [
|
export const GroupByTypes = [
|
||||||
FieldType.STRING,
|
FieldType.STRING,
|
||||||
FieldType.LONGFORM,
|
FieldType.LONGFORM,
|
||||||
|
|
Loading…
Reference in New Issue