import has from 'lodash/has' ; import { AndCondition , Condition , LeafCondition , OrCondition , RuleEffect , SchemaBasedCondition , Scopable , UISchemaElement } from '../models' ; import { resolveData } from './resolvers' ; import { composeWithUi } from './path' ; import Ajv from 'ajv' ; import { getAjv } from '../reducers' ; import { JsonFormsState } from '../store' ; import { JsonSchema } from '../models/jsonSchema' ; const isOrCondition = ( condition ) : condition is OrCondition => condition . type === 'OR' ; const isAndCondition = ( condition ) : condition is AndCondition => condition . type === 'AND' ; const isLeafCondition = ( condition ) : condition is LeafCondition => condition . type === 'LEAF' ; const isSchemaCondition = ( condition ) : condition is SchemaBasedCondition => has ( condition , 'schema' ) ; const getConditionScope = ( condition , path ) : string => { return composeWithUi ( condition , path ) ; } ; const evaluateCondition = ( data , condition , path , ajv ) : boolean => { if ( isAndCondition ( condition ) ) { return condition . conditions . reduce ( ( acc , cur ) => acc && evaluateCondition ( data , cur , path , ajv ) , true ) ; } else if ( isOrCondition ( condition ) ) { return condition . conditions . reduce ( ( acc , cur ) => acc || evaluateCondition ( data , cur , path , ajv ) , false ) ; } else if ( isLeafCondition ( condition ) ) { const value = resolveData ( data , getConditionScope ( condition , path ) ) ; return value === condition . expectedValue ; } else if ( isSchemaCondition ( condition ) ) { const value = resolveData ( data , getConditionScope ( condition , path ) ) ; return ajv . validate ( condition . schema , value ) as boolean ; } else { return true ; } } ; const isRuleFulfilled = ( uischema , data , path , ajv ) : boolean => { const condition = uischema . rule . condition ; return evaluateCondition ( data , condition , path , ajv ) ; } ; export const evalVisibility = ( uischema , data , path = undefined , ajv ) : boolean => { const fulfilled = isRuleFulfilled ( uischema , data , path , ajv ) ; switch ( uischema . rule . effect ) { case RuleEffect . HIDE : return ! fulfilled ; case RuleEffect . SHOW : return fulfilled ; default : return true ; } } ; export const evalEnablement = ( uischema , data , path = undefined , ajv ) : boolean => { const fulfilled = isRuleFulfilled ( uischema , data , path , ajv ) ; switch ( uischema . rule . effect ) { case RuleEffect . DISABLE : return ! fulfilled ; case RuleEffect . ENABLE : return fulfilled ; default : return true ; } } ; export const hasShowRule = ( uischema ) : boolean => { if ( uischema . rule && ( uischema . rule . effect === RuleEffect . SHOW || uischema . rule . effect === RuleEffect . HIDE ) ) { return true ; } return false ; } ; export const hasEnableRule = ( uischema ) : boolean => { if ( uischema . rule && ( uischema . rule . effect === RuleEffect . ENABLE || uischema . rule . effect === RuleEffect . DISABLE ) ) { return true ; } return false ; } ; export const isVisible = ( uischema , data , path = undefined , ajv ) : boolean => { if ( uischema . rule ) { return evalVisibility ( uischema , data , path , ajv ) ; } return true ; } ; export const isEnabled = ( uischema , data , path = undefined , ajv ) : boolean => { if ( uischema . rule ) { return evalEnablement ( uischema , data , path , ajv ) ; } return true ; } ; /**
 * Indicates whether the given `uischema` element shall be enabled or disabled.
 * Checks the global readonly flag, uischema rule, uischema options (including the config),
 * the schema and the enablement indicator of the parent.
 */ export const isInherentlyEnabled = ( state , ownProps , uischema , schema , rootData , config ) => { if ( state ?. jsonforms ?. readonly ) { return false ; } if ( uischema && hasEnableRule ( uischema ) ) { return isEnabled ( uischema , rootData , ownProps ?. path , getAjv ( state ) ) ; } if ( typeof uischema ?. options ?. readonly === 'boolean' ) { return ! uischema . options . readonly ; } if ( typeof uischema ?. options ?. readOnly === 'boolean' ) { return ! uischema . options . readOnly ; } if ( typeof config ?. readonly === 'boolean' ) { return ! config . readonly ; } if ( typeof config ?. readOnly === 'boolean' ) { return ! config . readOnly ; } if ( schema ?. readOnly === true ) { return false ; } if ( typeof ownProps ?. enabled === 'boolean' ) { return ownProps . enabled ; } return true ; } ;