diff --git a/packages/data-models/functions.ts b/packages/data-models/functions.ts index 883424d1a5..1d6940e02e 100644 --- a/packages/data-models/functions.ts +++ b/packages/data-models/functions.ts @@ -18,34 +18,36 @@ const DYNAMIC_STRING_REGEX = /[`!]?@([a-z]+)\.([0-9a-z_]+)([0-9a-z_.]*)/gi; * * Store these references in a separate object so they can be evaluated at runtime */ -export function extractDynamicFields(data: any) { +export function extractDynamicFields(data: any): FlowTypes.IDynamicField | undefined { + // only extract from string, array or nested json object types + if (!data || typeof data !== "object") return; + + // extract fields let dynamicFields: FlowTypes.IDynamicField = {}; - switch (typeof data) { - case "object": - // simply convert array to object to handle in next case - // ie. ["a","b"] => {0: "a", 1: "b"} - if (Array.isArray(data)) { - data = _arrayToObject(data); - } - if (data !== null) { - // data is a json-like object - Object.entries(data).forEach(([key, value]) => { - // skip processing some columns (remember these can be nested in other objects like parameter_list) - if (!["comments", "_dynamicFields"].includes(key)) { - const nestedDynamic = extractDynamicFields(value); - if (nestedDynamic) { - dynamicFields[key] = nestedDynamic; - } - } - }); + // simply convert array to object to handle in next case + // ie. ["a","b"] => {0: "a", 1: "b"} + if (Array.isArray(data)) { + data = _arrayToObject(data); + } + // data is a json-like object + Object.entries(data).forEach(([key, value]) => { + // skip processing some columns (remember these can be nested in other objects like parameter_list) + if (!["comments", "_dynamicFields"].includes(key)) { + let nestedDynamic: FlowTypes.IDynamicField | FlowTypes.TemplateRowDynamicEvaluator[] = + undefined; + if (typeof value === "string") { + // extract evaluators from string expression + nestedDynamic = extractDynamicEvaluators(value); + } else { + // extract evaluators from deeper nested objects or arrays + nestedDynamic = extractDynamicFields(value); } - break; - case "string": - const dynamicEvaluators = extractDynamicEvaluators(data as string); - if (dynamicEvaluators) { - return dynamicEvaluators; + if (nestedDynamic) { + dynamicFields[key] = nestedDynamic; } - } + } + }); + // nested dynamic fields are managed in the row themselves if (dynamicFields.hasOwnProperty("rows")) { delete dynamicFields["rows"]; diff --git a/packages/scripts/src/commands/app-data/convert/processors/flowParser/flowParser.ts b/packages/scripts/src/commands/app-data/convert/processors/flowParser/flowParser.ts index c0c162a950..e21473fdf3 100644 --- a/packages/scripts/src/commands/app-data/convert/processors/flowParser/flowParser.ts +++ b/packages/scripts/src/commands/app-data/convert/processors/flowParser/flowParser.ts @@ -4,7 +4,7 @@ import { IConverterPaths, IFlowHashmapByType, IParsedWorkbookData } from "../../ import { arrayToHashmap, groupJsonByKey, IContentsEntry } from "../../utils"; import BaseProcessor from "../base"; -const cacheVersion = 20240412.0; +const cacheVersion = 20240412.3; export class FlowParserProcessor extends BaseProcessor { public parsers: { [flowType in FlowTypes.FlowType]: Parsers.DefaultParser } = { diff --git a/src/app/feature/campaign/campaign.service.ts b/src/app/feature/campaign/campaign.service.ts index cfd2fb6d74..41a8136cfe 100644 --- a/src/app/feature/campaign/campaign.service.ts +++ b/src/app/feature/campaign/campaign.service.ts @@ -282,7 +282,7 @@ export class CampaignService extends AsyncServiceBase { // process translations first as these are made with dynamic content in place (e.g. "hello @name") const translatedRow = this.templateTranslateService.translateRow(row as any); // Continue processing full row - translatedRow._dynamicFields = extractDynamicFields(translatedRow) as FlowTypes.IDynamicField; + translatedRow._dynamicFields = extractDynamicFields(translatedRow); const parsedRow = await this.templateVariablesService.evaluatePLHData(translatedRow, { row: translatedRow, templateRowMap: {},