diff --git a/apps/builder/src/page/App/components/InspectPanel/PanelSetters/OptionListSetter/index.tsx b/apps/builder/src/page/App/components/InspectPanel/PanelSetters/OptionListSetter/index.tsx index 3acd862c20..937ade35cb 100644 --- a/apps/builder/src/page/App/components/InspectPanel/PanelSetters/OptionListSetter/index.tsx +++ b/apps/builder/src/page/App/components/InspectPanel/PanelSetters/OptionListSetter/index.tsx @@ -15,7 +15,7 @@ const OptionListSetter: FC = (props) => { widgetDisplayName, childrenSetter, handleUpdateMultiAttrDSL, - itemName, + itemName = "Option", } = props const execResult = useSelector(getExecutionResult) diff --git a/apps/builder/src/redux/currentApp/executionTree/executionListener.ts b/apps/builder/src/redux/currentApp/executionTree/executionListener.ts index f7eae8be88..0a501e5e6d 100644 --- a/apps/builder/src/redux/currentApp/executionTree/executionListener.ts +++ b/apps/builder/src/redux/currentApp/executionTree/executionListener.ts @@ -79,8 +79,11 @@ async function handleStartExecution( const isAddAction = action.type.startsWith("components/add") || action.type.startsWith("action/add") || - action.type.startsWith("action/batchAdd") - + action.type.startsWith("action/batchAdd") || + componentsActions.batchUpdateMultiComponentSlicePropsReducer.match( + action, + ) || + actionActions.batchUpdateMultiActionSlicePropsReducer.match(action) const executionResult = executionTree.updateTree( rawTree, isDeleteAction, diff --git a/apps/builder/src/utils/executionTreeHelper/executionTreeFactory.ts b/apps/builder/src/utils/executionTreeHelper/executionTreeFactory.ts index 0bc074c9b7..b38ba7f701 100644 --- a/apps/builder/src/utils/executionTreeHelper/executionTreeFactory.ts +++ b/apps/builder/src/utils/executionTreeHelper/executionTreeFactory.ts @@ -26,6 +26,7 @@ import { RawTreeShape } from "@/utils/executionTreeHelper/interface" import { extractReferencesFromScript, getImmediateParentsOfPropertyPaths, + getObjectPaths, isAction, isWidget, removeParentPath, @@ -133,6 +134,7 @@ export class ExecutionTreeFactory { getContainerListDisplayNameMappedChildrenNodeDisplayName( store.getState(), ) + const listWidgetDisplayNames = Object.keys(listWidgets) let currentListDisplayName = "" for (let i = 0; i < listWidgetDisplayNames.length; i++) { @@ -141,11 +143,13 @@ export class ExecutionTreeFactory { break } } + if (isObject(validationPaths)) { - Object.keys(validationPaths).forEach((validationPath) => { - const validationType = validationPaths[ - validationPath - ] as VALIDATION_TYPES + getObjectPaths(validationPaths).forEach((validationPath) => { + const validationType = get( + validationPaths, + validationPath, + ) as VALIDATION_TYPES const fullPath = `${displayName}.${validationPath}` const validationFunc = validationFactory[validationType] const value = get(widgetOrAction, validationPath) @@ -377,6 +381,7 @@ export class ExecutionTreeFactory { this.oldRawTree = klona(currentRawTree) const updatePaths = this.getUpdatePathFromDifferences(differences) const walkedPath = new Set() + let currentExecution = this.updateExecutionTreeByUpdatePaths( updatePaths, this.executedTree, @@ -401,6 +406,7 @@ export class ExecutionTreeFactory { path, -1, ) + this.mergeErrorTree(errorTree, [...updatePaths, ...path], isDeleteAction) this.mergeDebugDataTree( debuggerData, diff --git a/apps/builder/src/utils/executionTreeHelper/generateRawWidget.ts b/apps/builder/src/utils/executionTreeHelper/generateRawWidget.ts index c953a6202a..7fd6589136 100644 --- a/apps/builder/src/utils/executionTreeHelper/generateRawWidget.ts +++ b/apps/builder/src/utils/executionTreeHelper/generateRawWidget.ts @@ -11,6 +11,7 @@ export const generateRawWidget = (widget: WidgetShape) => { panelConfig, widget, ) + return { ...widget, $validationPaths: validationPaths, diff --git a/apps/builder/src/utils/executionTreeHelper/utils.ts b/apps/builder/src/utils/executionTreeHelper/utils.ts index c394181381..15c60050f3 100644 --- a/apps/builder/src/utils/executionTreeHelper/utils.ts +++ b/apps/builder/src/utils/executionTreeHelper/utils.ts @@ -136,3 +136,25 @@ export const removeWidgetOrActionMethods = ( {}, ) } + +export function getObjectPaths(obj: Record, currentPath = "") { + let paths: string[] = [] + + if (typeof obj === "object" && obj !== null) { + Object.keys(obj).forEach((key) => { + const value = obj[key] + const newPath = Array.isArray(obj) + ? `${currentPath}.${key}` + : `${currentPath ? currentPath + "." : ""}${key}` + if (typeof value === "object" && value !== null) { + paths = paths.concat( + getObjectPaths(value as Record, newPath), + ) + } else { + paths.push(newPath) + } + }) + } + + return paths.map((path) => (path.startsWith(".") ? path.substr(1) : path)) +} diff --git a/apps/builder/src/utils/generators/generateAllTypePathsFromWidgetConfig.ts b/apps/builder/src/utils/generators/generateAllTypePathsFromWidgetConfig.ts index 7bb58414b8..b20a138d82 100644 --- a/apps/builder/src/utils/generators/generateAllTypePathsFromWidgetConfig.ts +++ b/apps/builder/src/utils/generators/generateAllTypePathsFromWidgetConfig.ts @@ -1,5 +1,5 @@ import { convertPathToString } from "@illa-public/dynamic-string" -import { get, toPath } from "lodash-es" +import { get, set, toPath } from "lodash-es" import { PanelConfig, PanelFieldGroupConfig, @@ -23,11 +23,11 @@ export const generateAllTypePathsFromWidgetConfig = ( const expectedType = filedConfig.expectedType if (Array.isArray(expectedType)) { attrPath.forEach((path, i) => { - configValidationPaths[path] = expectedType[i] + set(configValidationPaths, path, expectedType[i]) }) } else if (expectedType) { attrPath.forEach((path) => { - configValidationPaths[path] = expectedType + set(configValidationPaths, path, expectedType) }) } } else { @@ -35,9 +35,9 @@ export const generateAllTypePathsFromWidgetConfig = ( const expectedType = filedConfig.expectedType if (Array.isArray(expectedType)) { - configValidationPaths[attrPath] = expectedType[0] + set(configValidationPaths, attrPath, expectedType[0]) } else if (expectedType) { - configValidationPaths[attrPath] = expectedType + set(configValidationPaths, attrPath, expectedType) } } } @@ -56,35 +56,43 @@ export const generateAllTypePathsFromWidgetConfig = ( if (Array.isArray(childAttrPath)) { if (Array.isArray(expectedType)) { childAttrPath.forEach((path, i) => { - configValidationPaths[ + set( + configValidationPaths, convertPathToString( toPath(`${objectIndexPropertyPath}.${path}`), - ) - ] = expectedType[i] + ), + expectedType[i], + ) }) } else if (expectedType) { childAttrPath.forEach((path) => { - configValidationPaths[ + set( + configValidationPaths, convertPathToString( toPath(`${objectIndexPropertyPath}.${path}`), - ) - ] = expectedType + ), + expectedType, + ) }) } } else { if (expectedType) { if (Array.isArray(expectedType)) { - configValidationPaths[ + set( + configValidationPaths, convertPathToString( toPath(`${objectIndexPropertyPath}.${childAttrPath}`), - ) - ] = expectedType[0] + ), + expectedType[0], + ) } else if (expectedType) { - configValidationPaths[ + set( + configValidationPaths, convertPathToString( toPath(`${objectIndexPropertyPath}.${childAttrPath}`), - ) - ] = expectedType + ), + expectedType, + ) } } } @@ -99,7 +107,11 @@ export const generateAllTypePathsFromWidgetConfig = ( filedConfig.childrenSetter?.forEach((childConfig) => { const expectedType = childConfig.expectedType if (!Array.isArray(expectedType) && expectedType) { - configValidationPaths[objectIndexPropertyPath] = expectedType + set( + configValidationPaths, + objectIndexPropertyPath, + expectedType, + ) } }) }) diff --git a/apps/builder/src/widgetLibrary/PC/GridListWidget/gridList.tsx b/apps/builder/src/widgetLibrary/PC/GridListWidget/gridList.tsx index 055dca9adf..31fcdd0a5f 100644 --- a/apps/builder/src/widgetLibrary/PC/GridListWidget/gridList.tsx +++ b/apps/builder/src/widgetLibrary/PC/GridListWidget/gridList.tsx @@ -10,6 +10,7 @@ import { getRawTree, } from "@/redux/currentApp/executionTree/executionSelector" import { evaluateDynamicString } from "@/utils/evaluateDynamicString" +import { getObjectPaths } from "@/utils/executionTreeHelper/utils" import { isObject } from "@/utils/typeHelper" import { VALIDATION_TYPES, validationFactory } from "@/utils/validationFactory" import ListWidgetWithAutoPagination from "./components/ListWidgetWithAutoPagination" @@ -85,7 +86,7 @@ export const GridListWidget: FC = (props) => { const rawWidget = rawTree[displayName] if (rawWidget && isObject(rawWidget.$validationPaths)) { const validationPaths = rawWidget.$validationPaths - const validationType = validationPaths[finalPath] + const validationType = get(validationPaths, finalPath) if (validationType === VALIDATION_TYPES.ARRAY) { const validationFunc = validationFactory[validationType] const res = validationFunc?.(evalResult, "") @@ -121,7 +122,7 @@ export const GridListWidget: FC = (props) => { const rawWidget = rawTree[realDisplayName as string] const validationPaths = rawWidget.$validationPaths if (isObject(validationPaths)) { - Object.keys(validationPaths).forEach((path) => { + getObjectPaths(validationPaths).forEach((path) => { const validationType = validationPaths[path] as VALIDATION_TYPES const validationFunc = validationFactory[validationType] const currentValue = get(item, `props.${path}`, "") diff --git a/apps/builder/src/widgetLibrary/PC/ListWidget/list.tsx b/apps/builder/src/widgetLibrary/PC/ListWidget/list.tsx index d9bebd8a8a..17be28f05f 100644 --- a/apps/builder/src/widgetLibrary/PC/ListWidget/list.tsx +++ b/apps/builder/src/widgetLibrary/PC/ListWidget/list.tsx @@ -10,6 +10,7 @@ import { getRawTree, } from "@/redux/currentApp/executionTree/executionSelector" import { evaluateDynamicString } from "@/utils/evaluateDynamicString" +import { getObjectPaths } from "@/utils/executionTreeHelper/utils" import { isObject } from "@/utils/typeHelper" import { VALIDATION_TYPES, validationFactory } from "@/utils/validationFactory" import { ListWidgetProps } from "@/widgetLibrary/PC/ListWidget/interface" @@ -86,7 +87,7 @@ export const ListWidget: FC = (props) => { const rawWidget = rawTree[displayName] if (rawWidget && isObject(rawWidget.$validationPaths)) { const validationPaths = rawWidget.$validationPaths - const validationType = validationPaths[finalPath] + const validationType = get(validationPaths, finalPath) if (validationType === VALIDATION_TYPES.ARRAY) { const validationFunc = validationFactory[validationType] const res = validationFunc?.(evalResult, "") @@ -122,8 +123,11 @@ export const ListWidget: FC = (props) => { const rawWidget = rawTree[realDisplayName as string] const validationPaths = rawWidget.$validationPaths if (isObject(validationPaths)) { - Object.keys(validationPaths).forEach((path) => { - const validationType = validationPaths[path] as VALIDATION_TYPES + getObjectPaths(validationPaths).forEach((path) => { + const validationType = get( + validationPaths, + path, + ) as VALIDATION_TYPES const validationFunc = validationFactory[validationType] const currentValue = get(item, `props.${path}`, "") const res = validationFunc?.(currentValue, "")