From 0d77896483bd0a8c14252c707f05e31e4fdc4cd5 Mon Sep 17 00:00:00 2001 From: brendanjbond Date: Fri, 10 Jan 2025 14:54:02 -0600 Subject: [PATCH 1/2] 1. Small formatting change to calculation/index.ts 2. Added a check for "includeAll" in eachComponentData when dealing w/ nested components (e.g. data grid) that will iterate over children regardless of whether there's data 3. Added a "getStringFromComponentPath" utility method --- src/process/calculation/index.ts | 2 +- src/utils/formUtil/eachComponentData.ts | 10 ++++++++++ src/utils/formUtil/eachComponentDataAsync.ts | 10 ++++++++++ src/utils/formUtil/index.ts | 16 ++++++++++++++++ 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/process/calculation/index.ts b/src/process/calculation/index.ts index 7375b03e..6d41166c 100644 --- a/src/process/calculation/index.ts +++ b/src/process/calculation/index.ts @@ -27,7 +27,7 @@ export const calculateProcessSync: ProcessorFnSync = ( } const calculationContext = (scope as FetchScope).fetched - ? {...context, data: {...data, ...(scope as FetchScope).fetched}} + ? { ...context, data: { ...data, ...(scope as FetchScope).fetched } } : context; const evalContextValue = evalContext ? evalContext(normalizeContext(calculationContext)) diff --git a/src/utils/formUtil/eachComponentData.ts b/src/utils/formUtil/eachComponentData.ts index 54aa7d5f..433738b4 100644 --- a/src/utils/formUtil/eachComponentData.ts +++ b/src/utils/formUtil/eachComponentData.ts @@ -83,6 +83,16 @@ export const eachComponentData = ( compPaths, ); } + } else if (includeAll) { + eachComponentData( + component.components, + data, + fn, + includeAll, + local, + component, + compPaths, + ); } resetComponentScope(component); return true; diff --git a/src/utils/formUtil/eachComponentDataAsync.ts b/src/utils/formUtil/eachComponentDataAsync.ts index f81f6f61..eff4b28f 100644 --- a/src/utils/formUtil/eachComponentDataAsync.ts +++ b/src/utils/formUtil/eachComponentDataAsync.ts @@ -77,6 +77,16 @@ export const eachComponentDataAsync = async ( compPaths, ); } + } else if (includeAll) { + await eachComponentDataAsync( + component.components, + data, + fn, + includeAll, + local, + component, + compPaths, + ); } resetComponentScope(component); return true; diff --git a/src/utils/formUtil/index.ts b/src/utils/formUtil/index.ts index 394769b3..51fd4f30 100644 --- a/src/utils/formUtil/index.ts +++ b/src/utils/formUtil/index.ts @@ -12,6 +12,7 @@ import { pad, isPlainObject, isArray, + isNumber, isEqual, isBoolean, omit, @@ -335,6 +336,21 @@ export function getComponentPaths( }; } +export function getStringFromComponentPath(path: string | string[]) { + if (!isArray(path)) { + return path; + } + let strPath = ''; + path.forEach((part, i) => { + if (isNumber(part)) { + strPath += `[${part}]`; + } else { + strPath += i === 0 ? part : `.${part}`; + } + }); + return strPath; +} + export type ComponentMatch = { component: Component | undefined; paths: ComponentPaths | undefined; From eff58e822c7f74a657ca1e495cac33c1687a53d2 Mon Sep 17 00:00:00 2001 From: brendanjbond Date: Fri, 10 Jan 2025 15:12:52 -0600 Subject: [PATCH 2/2] add tests --- .../__tests__/eachComponentData.test.ts | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/utils/formUtil/__tests__/eachComponentData.test.ts diff --git a/src/utils/formUtil/__tests__/eachComponentData.test.ts b/src/utils/formUtil/__tests__/eachComponentData.test.ts new file mode 100644 index 00000000..99bb61a0 --- /dev/null +++ b/src/utils/formUtil/__tests__/eachComponentData.test.ts @@ -0,0 +1,72 @@ +import { expect } from 'chai'; + +import { eachComponentData } from '../eachComponentData'; + +describe('eachComponentData', function () { + it('Should not iterate over each component in a nested component if includeAll=false and there is no data associated with the component', function () { + const components = [ + { + type: 'datagrid', + key: 'dataGrid', + label: 'Data Grid', + input: true, + components: [ + { + key: 'textField', + type: 'textfield', + label: 'Text Field', + input: true, + }, + ], + }, + ]; + + const data = {}; + + const rowResults: Map = new Map(); + eachComponentData( + components, + data, + (component, data, row, path) => { + rowResults.set(path, component.key); + }, + false, + ); + expect(rowResults.size).to.equal(1); + expect(rowResults.get('dataGrid')).to.deep.equal('dataGrid'); + }); + + it('Should iterate over each component in a nested component if includeAll=true and there is no data associated with the component', function () { + const components = [ + { + type: 'datagrid', + key: 'dataGrid', + label: 'Data Grid', + input: true, + components: [ + { + key: 'textField', + type: 'textfield', + label: 'Text Field', + input: true, + }, + ], + }, + ]; + + const data = {}; + + const rowResults: Map = new Map(); + eachComponentData( + components, + data, + (component, data, row, path) => { + rowResults.set(path, component.key); + }, + true, + ); + expect(rowResults.size).to.equal(2); + expect(rowResults.get('dataGrid')).to.deep.equal('dataGrid'); + expect(rowResults.get('dataGrid[0].textField')).to.deep.equal('textField'); + }); +});