From 063ebd9d057b3b3763fe9032b867d18182e87c2d Mon Sep 17 00:00:00 2001 From: Zhichao Gu Date: Tue, 22 Oct 2024 10:59:37 +0800 Subject: [PATCH] fix(formula): formula scope calc bug if fieldname like todos.0.sub_todos.0.title (#5469) --- .../src/client/components/Formula/Result.tsx | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/plugins/@nocobase/plugin-field-formula/src/client/components/Formula/Result.tsx b/packages/plugins/@nocobase/plugin-field-formula/src/client/components/Formula/Result.tsx index 52a88dc8da..7921af6f54 100644 --- a/packages/plugins/@nocobase/plugin-field-formula/src/client/components/Formula/Result.tsx +++ b/packages/plugins/@nocobase/plugin-field-formula/src/client/components/Formula/Result.tsx @@ -61,6 +61,21 @@ function getValuesByPath(values, key, index?) { } } +function getValuesByFullPath(values, fieldPath) { + const fieldPaths = fieldPath.split('.'); + let currentKeyIndex = 0; + let value = values; + //loop to get the last field + while (currentKeyIndex < fieldPaths.length) { + const fieldName = fieldPaths[currentKeyIndex]; + const index = parseInt(fieldPaths?.[currentKeyIndex + 1]); + value = getValuesByPath(value, fieldName, index); + //have index means an array, then jump 2; else 1 + currentKeyIndex = currentKeyIndex + (index >= 0 ? 2 : 1); + } + return value; +} + function areValuesEqual(value1, value2) { if (_.isString(value1) && !isNaN(Date.parse(value1))) { value1 = new Date(value1); @@ -87,8 +102,7 @@ export function Result(props) { const field: any = useField(); const path: any = field.path.entire; const fieldPath = path?.replace(`.${fieldSchema.name}`, ''); - const fieldName = fieldPath.split('.')[0]; - const index = parseInt(fieldPath.split('.')?.[1]); + useEffect(() => { setEditingValue(value); }, [value]); @@ -103,7 +117,9 @@ export function Result(props) { ) { return; } - const scope = toJS(getValuesByPath(form.values, fieldName, index)); + //field name may be like todos.0.sub_todos.0.title + //scope should be the deepest one + const scope = toJS(getValuesByFullPath(form.values, fieldPath)); let v; try { v = evaluate(expression, scope);