1
- import React , { useEffect , useReducer } from 'react' ;
1
+ import React , { useEffect , useReducer } from 'react' ;
2
2
import PropTypes from 'prop-types' ;
3
3
import lodashIsEmpty from 'lodash/isEmpty' ;
4
4
import get from 'lodash/get' ;
5
5
import isEqual from 'lodash/isEqual' ;
6
6
7
- import useFormApi from '../files/use-form-api' ;
7
+ const isEmptyValue = value =>
8
+ typeof value === 'number' || value === true ? false : lodashIsEmpty ( value ) ;
8
9
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} ) => {
12
11
if ( isNotEmpty ) {
13
12
return ! isEmptyValue ( value ) ;
14
13
}
@@ -29,126 +28,78 @@ const fieldCondition = (value, { is, isNotEmpty, isEmpty, pattern, notMatch, fla
29
28
} ;
30
29
31
30
export const parseCondition = ( condition , values ) => {
31
+ //Positive result is alwaus a triggering condition
32
+ //since a the clause always exists
32
33
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 ,
36
39
} ;
37
40
41
+ //if else clause exists, this is a triggered condition
42
+ //if no else clause exists, this is a non-triggering condition
38
43
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 ,
42
49
} ;
43
50
44
51
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 ;
46
57
}
47
58
48
59
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 )
50
63
? positiveResult
51
64
: negativeResult ;
52
65
}
53
66
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
-
69
67
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 ;
71
73
}
72
74
73
75
if ( condition . not ) {
74
- return ! parseCondition ( condition . not , values ) . result ? positiveResult : negativeResult ;
76
+ return ! parseCondition ( condition . not , values ) . triggered ? positiveResult : negativeResult ;
75
77
}
76
78
77
79
if ( typeof condition . when === 'string' ) {
78
80
return fieldCondition ( get ( values , condition . when ) , condition ) ? positiveResult : negativeResult ;
79
81
}
80
82
81
83
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 )
83
87
? positiveResult
84
88
: negativeResult ;
85
89
}
86
90
87
91
return negativeResult ;
88
92
} ;
89
93
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
-
149
94
const conditionProps = {
150
95
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
+ ] ) ,
152
103
isNotEmpty : PropTypes . bool ,
153
104
isEmpty : PropTypes . bool ,
154
105
pattern : ( props , name , componentName ) => {
@@ -166,30 +117,31 @@ const conditionProps = {
166
117
notMatch : PropTypes . any ,
167
118
then : PropTypes . shape ( {
168
119
visible : PropTypes . bool ,
169
- set : PropTypes . object
120
+ set : PropTypes . object ,
170
121
} ) ,
171
122
else : PropTypes . shape ( {
172
123
visible : PropTypes . bool ,
173
- set : PropTypes . object
174
- } )
124
+ set : PropTypes . object ,
125
+ } ) ,
175
126
} ;
176
127
177
128
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 ) ) ,
182
142
} ;
183
143
184
144
const conditionsProps = {
185
145
...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 ,
193
147
} ;
194
-
195
- export default Condition ;
0 commit comments