diff --git a/Changelog.md b/Changelog.md index d82a05a3..194fe1bf 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,6 @@ +## [Unreleased: 2.3.0-rc.9] + - FIO-8731: Update fix to nested hidden components + ## 2.3.0-rc.8 ### Changed - FIO-8723: Clear values from submission for hidden comp with clearOnHide flag diff --git a/src/process/conditions/index.ts b/src/process/conditions/index.ts index c68a66d4..211a702e 100644 --- a/src/process/conditions/index.ts +++ b/src/process/conditions/index.ts @@ -79,7 +79,7 @@ export const isConditionallyHidden = (context: ConditionsContext): boolean => { export type ConditionallyHidden = (context: ConditionsContext) => boolean; export const conditionalProcess = (context: ConditionsContext, isHidden: ConditionallyHidden) => { - const { component, scope, path } = context; + const { component, row, scope, path } = context; if (!hasConditions(context)) { return; } @@ -93,6 +93,9 @@ export const conditionalProcess = (context: ConditionsContext, isHidden: Conditi } conditionalComp.conditionallyHidden = conditionalComp.conditionallyHidden || isHidden(context); + if (conditionalComp.conditionallyHidden) { + set(component, 'hidden', true); + } }; export const customConditionProcess: ProcessorFn = async (context: ConditionsContext) => { diff --git a/src/process/hideChildren.ts b/src/process/hideChildren.ts new file mode 100644 index 00000000..2d2c81de --- /dev/null +++ b/src/process/hideChildren.ts @@ -0,0 +1,56 @@ +import { set } from 'lodash'; +import { + ProcessorScope, + ProcessorContext, + ProcessorInfo, + ProcessorFnSync, + ConditionsScope, + Component, + ProcessorFn, +} from "types"; +import { componentInfo, eachComponentData, getComponentPath } from 'utils/formUtil'; + +/** + * This processor function checks components for the `hidden` property and, if children are present, sets them to hidden as well. + */ +export const hideChildrenProcessor: ProcessorFnSync = (context) => { + const { component, path, row, scope } = context; + // Check if there's a conditional set for the component and if it's marked as conditionally hidden + const isConditionallyHidden = scope.conditionals?.find((cond) => { + return path.includes(cond.path) && cond.conditionallyHidden; + }); + if (component.hidden && isConditionallyHidden) { + const info = componentInfo(component); + if (info.hasColumns || info.hasComps || info.hasRows) { + // If this is a container component, we need to make the mutation to all the child components as well. + eachComponentData([component], row, (comp: Component, data: any, compRow: any, compPath: string) => { + if (comp !== component) { + // the path set here is not the absolute path, but the path relative to the parent component + (scope as ConditionsScope).conditionals?.push({ path: getComponentPath(comp, compPath), conditionallyHidden: true }); + set(comp, 'hidden', true); + } + }); + } + } else if (component.hidden) { + const info = componentInfo(component); + if (info.hasColumns || info.hasComps || info.hasRows) { + // If this is a container component, we need to make the mutation to all the child components as well. + eachComponentData([component], row, (comp: Component, data: any, compRow: any, compPath: string) => { + if (comp !== component) { + set(comp, 'hidden', true); + } + }); + } + } +} + +export const hideChildrenProcessorAsync: ProcessorFn = async (context) => { + return hideChildrenProcessor(context); +}; + +export const hideChildrenProcessorInfo: ProcessorInfo, void> = { + name: 'hideChildren', + shouldProcess: () => true, + processSync: hideChildrenProcessor, + process: hideChildrenProcessorAsync, +} diff --git a/src/process/index.ts b/src/process/index.ts index ad881c99..423b0417 100644 --- a/src/process/index.ts +++ b/src/process/index.ts @@ -11,4 +11,4 @@ export * from './process'; export * from './normalize'; export * from './dereference'; export * from './clearHidden'; -export * from './hiddenChildren' +export * from './hideChildren'; diff --git a/src/process/process.ts b/src/process/process.ts index b7ac0e56..8843b42d 100644 --- a/src/process/process.ts +++ b/src/process/process.ts @@ -28,7 +28,7 @@ import { filterProcessInfo } from './filter'; import { normalizeProcessInfo } from './normalize'; import { dereferenceProcessInfo } from './dereference'; import { clearHiddenProcessInfo } from './clearHidden'; -import { hiddenChildrenProcessorInfo } from './hiddenChildren'; +import { hideChildrenProcessorInfo } from './hideChildren'; export async function process( context: ProcessContext @@ -131,7 +131,7 @@ export const ProcessorMap: Record> = { validate: validateProcessInfo, validateCustom: validateCustomProcessInfo, validateServer: validateServerProcessInfo, - hiddenChildren: hiddenChildrenProcessorInfo + hideChildren: hideChildrenProcessorInfo }; export const ProcessTargets: ProcessTarget = { @@ -149,7 +149,7 @@ export const ProcessTargets: ProcessTarget = { calculateProcessInfo, logicProcessInfo, conditionProcessInfo, - hiddenChildrenProcessorInfo, + hideChildrenProcessorInfo, clearHiddenProcessInfo, validateProcessInfo, ], diff --git a/src/utils/logic.ts b/src/utils/logic.ts index 06bad6cd..c88f4977 100644 --- a/src/utils/logic.ts +++ b/src/utils/logic.ts @@ -3,6 +3,7 @@ import { checkCustomConditional, checkJsonConditional, checkLegacyConditional, c import { LogicActionCustomAction, LogicActionMergeComponentSchema, LogicActionProperty, LogicActionPropertyBoolean, LogicActionPropertyString, LogicActionValue } from "types/AdvancedLogic"; import { get, set, clone, isEqual, assign } from 'lodash'; import { evaluate, interpolate } from 'modules/jsonlogic'; +import { componentInfo, eachComponentData, getComponentPath } from "./formUtil"; export const hasLogic = (context: LogicContext): boolean => { const { component } = context; @@ -69,6 +70,7 @@ export function setActionBooleanProperty(context: LogicContext, action: LogicAct conditionallyHidden: !!component.hidden, }); } + set(component, 'hidden', !!component.hidden); } return true; }