1- import React , { useEffect , useReducer } from 'react' ;
1+ import React , { useEffect , useReducer } from 'react' ;
22import PropTypes from 'prop-types' ;
33import lodashIsEmpty from 'lodash/isEmpty' ;
44import get from 'lodash/get' ;
55import 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
3130export 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-
14994const 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
177128const 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
184144const 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 ;
0 commit comments