Skip to content

Commit a6b85fd

Browse files
committed
fix(renderer): add mapped conditions to condition triggers
1 parent 3c2dd06 commit a6b85fd

File tree

4 files changed

+54
-6
lines changed

4 files changed

+54
-6
lines changed

packages/react-form-renderer/src/form-renderer/render-form.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ ConditionTriggerDetector.propTypes = {
6767
field: PropTypes.object.isRequired,
6868
};
6969

70-
const FormConditionWrapper = ({ condition, children, field }) => {
70+
const FormConditionWrapper = ({ condition, children, field, conditionMapper }) => {
7171
if (condition) {
72-
const triggers = getConditionTriggers(condition, field);
72+
const triggers = getConditionTriggers(condition, field, conditionMapper);
7373
return (
7474
<ConditionTriggerDetector triggers={triggers} condition={condition} field={field}>
7575
{children}
@@ -84,10 +84,11 @@ FormConditionWrapper.propTypes = {
8484
condition: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
8585
children: PropTypes.node.isRequired,
8686
field: PropTypes.object,
87+
conditionMapper: PropTypes.object,
8788
};
8889

8990
const SingleField = ({ component, ...rest }) => {
90-
const { actionMapper, componentMapper } = useContext(RendererContext);
91+
const { actionMapper, componentMapper, conditionMapper } = useContext(RendererContext);
9192

9293
const { componentProps, Component, overrideProps, mergedResolveProps } = prepareComponentProps({ component, rest, componentMapper, actionMapper });
9394

@@ -98,7 +99,7 @@ const SingleField = ({ component, ...rest }) => {
9899
};
99100

100101
return (
101-
<FormConditionWrapper condition={condition} field={restProps}>
102+
<FormConditionWrapper condition={condition} field={restProps} conditionMapper={conditionMapper}>
102103
<FormFieldHideWrapper hideField={hideField}>
103104
<Component {...restProps} />
104105
</FormFieldHideWrapper>
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import { Field } from "../common-types";
12
import { ConditionDefinition } from "../condition";
3+
import { ConditionMapper } from "../form-renderer/condition-mapper";
24

3-
declare function getConditionTriggers(params:ConditionDefinition | ConditionDefinition[]): string[];
5+
declare function getConditionTriggers(params:ConditionDefinition | ConditionDefinition[], field: Extract<Field, 'condition' | 'hideField'>, conditionMapper: ConditionMapper): string[];
46

57
export default getConditionTriggers;

packages/react-form-renderer/src/get-condition-triggers/get-condition-triggers.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,29 @@ const mergeFunctionTrigger = (fn, field) => {
1010
return internalTriggers;
1111
};
1212

13-
const getConditionTriggers = (condition, field) => {
13+
const getConditionTriggers = (condition, field, conditionMapper = {}) => {
1414
let triggers = [];
1515
if (Array.isArray(condition)) {
1616
return condition.reduce((acc, item) => [...acc, ...getConditionTriggers(item, field)], []);
1717
}
1818

19+
// extract mapped attributes to a new static condition object
20+
if (typeof condition.mappedAttributes === 'object') {
21+
try {
22+
const newCondition = { ...condition, mappedAttributes: undefined };
23+
Object.entries(condition.mappedAttributes).forEach(([attribute, [functionName, ...args]]) => {
24+
if (!conditionMapper[functionName]) {
25+
throw new Error(`Missing condition mapper function "${functionName}" for field ${field.name}!`);
26+
}
27+
28+
newCondition[attribute] = conditionMapper[functionName](...args);
29+
});
30+
return getConditionTriggers(newCondition, field, conditionMapper);
31+
} catch (error) {
32+
console.error(error.toString());
33+
}
34+
}
35+
1936
const { when, ...rest } = condition;
2037
const nestedKeys = ['and', 'or', 'sequence'];
2138
if (typeof when === 'string') {

packages/react-form-renderer/src/tests/get-condition-triggers/get-condition-triggers.test.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,32 @@ describe('getConditionTriggers', () => {
3232
test('should extract name from array of conditions', () => {
3333
expect(getConditionTriggers([{ when: 'a' }, { when: 'b' }])).toEqual(['a', 'b']);
3434
});
35+
36+
describe('mappedAttributes', () => {
37+
it(`should extract the 'when' attribute from mappedAttributes`, () => {
38+
expect(
39+
getConditionTriggers(
40+
{ mappedAttributes: { when: ['equals', 'a'] } },
41+
{},
42+
{
43+
equals: (a) => () => a,
44+
}
45+
)
46+
).toEqual(['a']);
47+
});
48+
it(`should log error if mapped condition is missing from condition mapper`, () => {
49+
const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
50+
expect(
51+
getConditionTriggers(
52+
{ mappedAttributes: { when: ['equals', 'a'] } },
53+
{ name: 'foo' },
54+
// conditionMapper is deliberately empty
55+
{}
56+
)
57+
).toEqual([]);
58+
expect(consoleSpy).toHaveBeenCalledTimes(1);
59+
expect(consoleSpy).toHaveBeenCalledWith(`Error: Missing condition mapper function "equals" for field foo!`);
60+
consoleSpy.mockRestore();
61+
});
62+
});
3563
});

0 commit comments

Comments
 (0)