Skip to content

Commit 98d2064

Browse files
committed
Replaced old Condition component
N.B. legacy condition definitions will not work in this version. A soon to come legacyConditionsMapper will solve this. chore: replaced condition.js with condition2.js (new handler) chore: removed Conditions and FormConditionsWrapper components from render-form.js chore: implemented new conditions-handler in render-form.js, including support for "visible" and "disabled"
1 parent 3c683cd commit 98d2064

File tree

4 files changed

+102
-289
lines changed

4 files changed

+102
-289
lines changed

packages/react-form-renderer/src/files/register-conditions.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {useFormApi} from '../';
33
import {Field} from 'react-final-form';
44

55
import {conditionsMapper} from './conditions-mapper';
6-
import {parseCondition} from '../form-renderer/condition2';
6+
import {parseCondition} from '../form-renderer/condition';
77

88
const RegisterConditions = ({schema}) => {
99
const {getState, registerField, dispatchUIState} = useFormApi();
Lines changed: 59 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
import React, { useEffect, useReducer } from 'react';
1+
import React, {useEffect, useReducer} from 'react';
22
import PropTypes from 'prop-types';
33
import lodashIsEmpty from 'lodash/isEmpty';
44
import get from 'lodash/get';
55
import isEqual from 'lodash/isEqual';
66

7-
import useFormApi from '../files/use-form-api';
7+
const isEmptyValue = value =>
8+
typeof value === 'number' || value === true ? false : lodashIsEmpty(value);
89

9-
const isEmptyValue = (value) => (typeof value === 'number' || value === true ? false : lodashIsEmpty(value));
10-
11-
const fieldCondition = (value, { is, isNotEmpty, isEmpty, pattern, notMatch, flags }) => {
10+
const fieldCondition = (value, {is, isNotEmpty, isEmpty, pattern, notMatch, flags}) => {
1211
if (isNotEmpty) {
1312
return !isEmptyValue(value);
1413
}
@@ -29,126 +28,78 @@ const fieldCondition = (value, { is, isNotEmpty, isEmpty, pattern, notMatch, fla
2928
};
3029

3130
export const parseCondition = (condition, values) => {
31+
//Positive result is alwaus a triggering condition
32+
//since a the clause always exists
3233
let positiveResult = {
33-
visible: true,
34-
...condition.then,
35-
result: true
34+
uiState: {
35+
add: condition.then,
36+
remove: condition.else,
37+
},
38+
triggered: true,
3639
};
3740

41+
//if else clause exists, this is a triggered condition
42+
//if no else clause exists, this is a non-triggering condition
3843
let negativeResult = {
39-
visible: false,
40-
...condition.else,
41-
result: false
44+
uiState: {
45+
add: condition.else,
46+
remove: condition.then,
47+
},
48+
triggered: condition.else ? true : false,
4249
};
4350

4451
if (Array.isArray(condition)) {
45-
return !condition.map((condition) => parseCondition(condition, values)).some(({ result }) => result === false) ? positiveResult : negativeResult;
52+
return !condition
53+
.map(condition => parseCondition(condition, values))
54+
.some(({triggered}) => triggered === false)
55+
? positiveResult
56+
: negativeResult;
4657
}
4758

4859
if (condition.and) {
49-
return !condition.and.map((condition) => parseCondition(condition, values)).some(({ result }) => result === false)
60+
return !condition.and
61+
.map(condition => parseCondition(condition, values))
62+
.some(({triggered}) => triggered === false)
5063
? positiveResult
5164
: negativeResult;
5265
}
5366

54-
if (condition.sequence) {
55-
return condition.sequence.reduce(
56-
(acc, curr) => {
57-
const result = parseCondition(curr, values);
58-
59-
return {
60-
sets: [...acc.sets, ...(result.set ? [result.set] : [])],
61-
visible: acc.visible || result.visible,
62-
result: acc.result || result.result
63-
};
64-
},
65-
{ ...negativeResult, sets: [] }
66-
);
67-
}
68-
6967
if (condition.or) {
70-
return condition.or.map((condition) => parseCondition(condition, values)).some(({ result }) => result === true) ? positiveResult : negativeResult;
68+
return condition.or
69+
.map(condition => parseCondition(condition, values))
70+
.some(({triggered}) => triggered === true)
71+
? positiveResult
72+
: negativeResult;
7173
}
7274

7375
if (condition.not) {
74-
return !parseCondition(condition.not, values).result ? positiveResult : negativeResult;
76+
return !parseCondition(condition.not, values).triggered ? positiveResult : negativeResult;
7577
}
7678

7779
if (typeof condition.when === 'string') {
7880
return fieldCondition(get(values, condition.when), condition) ? positiveResult : negativeResult;
7981
}
8082

8183
if (Array.isArray(condition.when)) {
82-
return condition.when.map((fieldName) => fieldCondition(get(values, fieldName), condition)).find((condition) => !!condition)
84+
return condition.when
85+
.map(fieldName => fieldCondition(get(values, fieldName), condition))
86+
.find(condition => !!condition)
8387
? positiveResult
8488
: negativeResult;
8589
}
8690

8791
return negativeResult;
8892
};
8993

90-
export const reducer = (state, { type, sets }) => {
91-
switch (type) {
92-
case 'formResetted':
93-
return {
94-
...state,
95-
initial: true
96-
};
97-
case 'rememberSets':
98-
return {
99-
...state,
100-
initial: false,
101-
sets
102-
};
103-
default:
104-
return state;
105-
}
106-
};
107-
108-
const Condition = React.memo(
109-
({ condition, children, values }) => {
110-
const formOptions = useFormApi();
111-
const dirty = formOptions.getState().dirty;
112-
113-
const [state, dispatch] = useReducer(reducer, {
114-
sets: [],
115-
initial: true
116-
});
117-
118-
const conditionResult = parseCondition(condition, values, formOptions);
119-
const setters = conditionResult.set ? [conditionResult.set] : conditionResult.sets;
120-
121-
useEffect(() => {
122-
if (!dirty) {
123-
dispatch({ type: 'formResetted' });
124-
}
125-
}, [dirty]);
126-
127-
useEffect(() => {
128-
if (setters && setters.length > 0 && (state.initial || !isEqual(setters, state.sets))) {
129-
setters.forEach((setter, index) => {
130-
if (setter && (state.initial || !isEqual(setter, state.sets[index]))) {
131-
setTimeout(() => {
132-
formOptions.batch(() => {
133-
Object.entries(setter).forEach(([name, value]) => {
134-
formOptions.change(name, value);
135-
});
136-
});
137-
});
138-
}
139-
});
140-
dispatch({ type: 'rememberSets', sets: setters });
141-
}
142-
}, [setters, state.initial]);
143-
144-
return conditionResult.visible ? children : null;
145-
},
146-
(a, b) => isEqual(a.values, b.values) && isEqual(a.condition, b.condition)
147-
);
148-
14994
const conditionProps = {
15095
when: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
151-
is: PropTypes.oneOfType([PropTypes.array, PropTypes.string, PropTypes.object, PropTypes.number, PropTypes.bool]),
96+
is: PropTypes.oneOfType([
97+
PropTypes.array,
98+
PropTypes.string,
99+
PropTypes.object,
100+
PropTypes.number,
101+
PropTypes.bool,
102+
]),
152103
isNotEmpty: PropTypes.bool,
153104
isEmpty: PropTypes.bool,
154105
pattern: (props, name, componentName) => {
@@ -166,30 +117,31 @@ const conditionProps = {
166117
notMatch: PropTypes.any,
167118
then: PropTypes.shape({
168119
visible: PropTypes.bool,
169-
set: PropTypes.object
120+
set: PropTypes.object,
170121
}),
171122
else: PropTypes.shape({
172123
visible: PropTypes.bool,
173-
set: PropTypes.object
174-
})
124+
set: PropTypes.object,
125+
}),
175126
};
176127

177128
const nestedConditions = {
178-
or: PropTypes.oneOfType([PropTypes.shape(conditionProps), PropTypes.arrayOf(PropTypes.shape(conditionProps))]),
179-
and: PropTypes.oneOfType([PropTypes.shape(conditionProps), PropTypes.arrayOf(PropTypes.shape(conditionProps))]),
180-
not: PropTypes.oneOfType([PropTypes.shape(conditionProps), PropTypes.arrayOf(PropTypes.shape(conditionProps))]),
181-
sequence: PropTypes.arrayOf(PropTypes.shape(conditionProps))
129+
or: PropTypes.oneOfType([
130+
PropTypes.shape(conditionProps),
131+
PropTypes.arrayOf(PropTypes.shape(conditionProps)),
132+
]),
133+
and: PropTypes.oneOfType([
134+
PropTypes.shape(conditionProps),
135+
PropTypes.arrayOf(PropTypes.shape(conditionProps)),
136+
]),
137+
not: PropTypes.oneOfType([
138+
PropTypes.shape(conditionProps),
139+
PropTypes.arrayOf(PropTypes.shape(conditionProps)),
140+
]),
141+
sequence: PropTypes.arrayOf(PropTypes.shape(conditionProps)),
182142
};
183143

184144
const conditionsProps = {
185145
...conditionProps,
186-
...nestedConditions
187-
};
188-
189-
Condition.propTypes = {
190-
condition: PropTypes.oneOfType([PropTypes.shape(conditionsProps), PropTypes.arrayOf(PropTypes.shape(conditionsProps))]),
191-
children: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)]).isRequired,
192-
values: PropTypes.object.isRequired
146+
...nestedConditions,
193147
};
194-
195-
export default Condition;

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

Lines changed: 0 additions & 147 deletions
This file was deleted.

0 commit comments

Comments
 (0)