diff --git a/packages/nc-gui/components/smartsheet/column/FormulaOptions.vue b/packages/nc-gui/components/smartsheet/column/FormulaOptions.vue index 45624cf039..1cd4dfcb3e 100644 --- a/packages/nc-gui/components/smartsheet/column/FormulaOptions.vue +++ b/packages/nc-gui/components/smartsheet/column/FormulaOptions.vue @@ -2,6 +2,14 @@ import type { Ref } from 'vue' import type { ListItem as AntListItem } from 'ant-design-vue' import jsep from 'jsep' +import type { ColumnType, FormulaType } from 'nocodb-sdk' +import { + FormulaError, + UITypes, + jsepCurlyHook, + substituteColumnIdWithAliasInFormula, + validateFormulaAndExtractTreeWithType, +} from 'nocodb-sdk' import type { ColumnType, FormulaType, LinkToAnotherRecordType, TableType } from 'nocodb-sdk' import { UITypes, @@ -52,10 +60,6 @@ const { setAdditionalValidations, validateInfos, sqlUi, column } = useColumnCrea const { t } = useI18n() -const baseStore = useBase() - -const { tables } = storeToRefs(baseStore) - const { predictFunction: _predictFunction } = useNocoEe() enum JSEPNode { @@ -103,6 +107,10 @@ const validators = { try { validateFormulaAndExtractTreeWithType(formula, supportedColumns.value) } catch (e: any) { + if (e instanceof FormulaError && e.extra?.key) { + return reject(new Error(t(e.extra.key, e.extra))) + } + return reject(new Error(e.message)) } // if (res !== true) { diff --git a/packages/nocodb-sdk/src/lib/formulaHelpers.ts b/packages/nocodb-sdk/src/lib/formulaHelpers.ts index 5f365fbab2..7198412eec 100644 --- a/packages/nocodb-sdk/src/lib/formulaHelpers.ts +++ b/packages/nocodb-sdk/src/lib/formulaHelpers.ts @@ -102,7 +102,7 @@ export async function substituteColumnAliasWithIdInFormula( return jsepTreeToFormula(parsedFormula); } -enum FormulaErrorType { +export enum FormulaErrorType { NOT_AVAILABLE = 'NOT_AVAILABLE', NOT_SUPPORTED = 'NOT_SUPPORTED', MIN_ARG = 'MIN_ARG', @@ -1152,7 +1152,7 @@ const formulas: Record = { // }, }; -class FormulaError extends Error { +export class FormulaError extends Error { public type: FormulaErrorType; public extra: Record; @@ -1265,15 +1265,28 @@ export function validateFormulaAndExtractTreeWithType( (argType) => argType !== expectedArgType && argType !== FormulaDataTypes.NULL ) - ) + ) { + let key = ''; + + if (expectedArgType === FormulaDataTypes.NUMERIC) { + key = 'msg.formula.numericTypeIsExpected'; + } else if (expectedArgType === FormulaDataTypes.STRING) { + key = 'msg.formula.stringTypeIsExpected'; + } else if (expectedArgType === FormulaDataTypes.BOOLEAN) { + key = 'msg.formula.booleanTypeIsExpected'; + } else if (expectedArgType === FormulaDataTypes.DATE) { + key = 'msg.formula.dateTypeIsExpected'; + } + throw new FormulaError( FormulaErrorType.INVALID_ARG, { - key: 'msg.formula.invalidArgumentType', + key, calleeName, }, 'Invalid argument type' ); + } } if (typeof formulas[calleeName].returnType === 'function') { diff --git a/packages/nocodb/src/services/columns.service.ts b/packages/nocodb/src/services/columns.service.ts index f9731fc115..81c261f421 100644 --- a/packages/nocodb/src/services/columns.service.ts +++ b/packages/nocodb/src/services/columns.service.ts @@ -233,7 +233,7 @@ export class ColumnsService { {}, null, true, - colBody.parsed_tree + colBody.parsed_tree, ); } catch (e) { console.error(e); @@ -938,7 +938,10 @@ export class ColumnsService { ]); await FormulaColumn.update(c.id, { formula_raw: new_formula_raw, - parsed_tree: validateFormulaAndExtractTreeWithType(new_formula_raw, table.columns) + parsed_tree: validateFormulaAndExtractTreeWithType( + new_formula_raw, + table.columns, + ), }); } } @@ -1209,10 +1212,15 @@ export class ColumnsService { colBody.formula_raw || colBody.formula, table.columns, ); + console.log( + colBody.formula_raw || + colBody.formula?.replaceAll('{{', '{').replaceAll('}}', '}'), + ); colBody.parsed_tree = validateFormulaAndExtractTreeWithType( // formula may include double curly brackets in previous version // convert to single curly bracket here for compatibility - colBody.formula_raw || colBody.formula?.replaceAll('{{', '{').replaceAll('}}', '}'), + colBody.formula_raw || + colBody.formula?.replaceAll('{{', '{').replaceAll('}}', '}'), table.columns, );