Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIO-8100: add clearhidden processor to cover logic, conditions, and custom #64

Merged
merged 3 commits into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 128 additions & 6 deletions src/process/__tests__/process.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2541,6 +2541,128 @@ describe('Process Tests', () => {
assert.deepEqual(context.data, { selector: 'one' });
assert.equal(context.scope.errors.length, 0);
});

it('Should not include submission data for conditionally hidden fields', async () => {
const form = {
display: 'form',
components: [
{
type: 'textfield',
key: 'textField',
label: 'Text Field',
input: true,
},
{
type: 'textarea',
key: 'textArea',
label: 'Text Area',
input: true,
conditional: {
show: false,
conjunction: 'all',
conditions: [
{
component: 'textField',
operator: 'isEmpty'
}
]
},
}
]
};

const submission = {
data: {
textField: '',
textArea: 'should not be in submission'
}
};

const context = {
form,
submission,
data: submission.data,
components: form.components,
processors: ProcessTargets.evaluator,
scope: {},
config: {
server: true
}
};
processSync(context);
expect(context.data).to.deep.equal({ textField: '' });
});

it('Should not include submission data for logically hidden fields', async () => {
const form = {
display: 'form',
components: [
{
type: 'textfield',
key: 'textField',
label: 'Text Field',
input: true,
},
{
type: 'textarea',
key: 'textArea',
label: 'Text Area',
input: true,
logic: [
{
name: 'Hide When Empty',
trigger: {
type: 'simple' as const,
simple: {
show: true,
conjunction: 'all',
conditions: [
{
component: 'textField',
operator: 'isEmpty',
},
],
},
},
actions: [
{
name: 'Hide',
type: 'property' as const,
property: {
label: 'Hidden',
value: 'hidden',
type: 'boolean' as const,
},
state: true,
},
],
},
]
}
]
};

const submission = {
data: {
textField: '',
textArea: 'should not be in submission'
}
};

const context = {
form,
submission,
data: submission.data,
components: form.components,
processors: ProcessTargets.evaluator,
scope: {},
config: {
server: true
}
};
processSync(context);
expect(context.data).to.deep.equal({ textField: '' });
});
/*
it('Should not clearOnHide when set to false', async () => {
var components = [
Expand Down Expand Up @@ -2621,7 +2743,7 @@ describe('Process Tests', () => {
}
}
];

helper
.form('test', components)
.submission({
Expand All @@ -2632,13 +2754,13 @@ describe('Process Tests', () => {
if (err) {
return done(err);
}

var submission = helper.getLastSubmission();
assert.deepEqual({selector: 'one', noClear: 'testing'}, submission.data);
done();
});
});

it('Should clearOnHide when set to true', async () => {
var components = [
{
Expand Down Expand Up @@ -2718,7 +2840,7 @@ describe('Process Tests', () => {
}
}
];

helper
.form('test', components)
.submission({
Expand All @@ -2729,11 +2851,11 @@ describe('Process Tests', () => {
if (err) {
return done(err);
}

var submission = helper.getLastSubmission();
assert.deepEqual({selector: 'one'}, submission.data);
done();
});
});
*/
});
});
33 changes: 33 additions & 0 deletions src/process/clearHidden.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import unset from 'lodash/unset';
import {
ProcessorScope,
ProcessorContext,
ProcessorInfo,
ProcessorFnSync
} from "types";

type ClearHiddenScope = ProcessorScope & {
clearHidden: {
[path: string]: boolean;
}
}

/**
* This processor function checks components for the `hidden` property and unsets corresponding data
*/
export const clearHiddenProcess: ProcessorFnSync<ClearHiddenScope> = (context) => {
const { component, data, path, value, scope } = context;
if (!scope.clearHidden) {
scope.clearHidden = {};
}
if (component.hidden && value !== undefined && (!component.hasOwnProperty('clearOnHide') || component.clearOnHide)) {
unset(data, path);
brendanbond marked this conversation as resolved.
Show resolved Hide resolved
scope.clearHidden[path] = true;
}
}

export const clearHiddenProcessInfo: ProcessorInfo<ProcessorContext<ClearHiddenScope>, void> = {
name: 'clearHidden',
shouldProcess: () => true,
processSync: clearHiddenProcess,
}
38 changes: 24 additions & 14 deletions src/process/conditions/__tests__/conditions.test.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,54 @@
import { expect } from 'chai';
import { process } from '../../process'
import { processSync } from '../../process'
import { conditionProcessInfo } from '../index';
import { ConditionsScope, ProcessContext } from 'types';

const processForm = async (form: any, submission: any) => {
const processForm = (form: any, submission: any) => {
const context: ProcessContext<ConditionsScope> = {
processors: [conditionProcessInfo],
components: form.components,
data: submission.data,
scope: {}
};
await process(context);
processSync(context);
return context;
};

describe('Condition processor', () => {
it('Perform conditional data with "clearOnHide" enabled.', async () => {
it('Should modify component\'s "hidden" property when conditionally visible is false', async () => {
const form = {
components: [
{
type: 'number',
type: 'textfield',
key: 'a',
input: true
},
{
type: 'number',
type: 'textfield',
key: 'b',
input: true
input: true,
conditional: {
show: false,
conjunction: 'all',
conditions: [
{
component: 'a',
operator: 'isEmpty'
}
]
},
}
]
};

const submission = {
data: {
a: 1,
b: 2
a: '',
}
};

const context: ProcessContext<ConditionsScope> = await processForm(form, submission);
console.log(context);

const context: ProcessContext<ConditionsScope> = processForm(form, submission);
expect(context.components[1]).to.haveOwnProperty('hidden');
expect(context.components[1].hidden).to.be.true;
});
});
});
10 changes: 3 additions & 7 deletions src/process/conditions/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ProcessorFn, ProcessorFnSync, ConditionsScope, ProcessorInfo, ConditionsContext, SimpleConditional, JSONConditional, LegacyConditional, SimpleConditionalConditions, Component, NestedComponent, FilterScope } from 'types';
import { Utils } from 'utils';
import unset from 'lodash/unset';
import set from 'lodash/set';
import { componentInfo, getComponentKey, getComponentPath } from 'utils/formUtil';
import {
checkCustomConditional,
Expand Down Expand Up @@ -112,16 +112,12 @@ export const conditionalProcess = (context: ConditionsContext, isHidden: Conditi
Utils.eachComponentData([component], row, (comp: Component, data: any, compRow: any, compPath: string) => {
if (comp !== component) {
scope.conditionals?.push({ path: getComponentPath(comp, compPath), conditionallyHidden: true });
}
if (!comp.hasOwnProperty('clearOnHide') || comp.clearOnHide) {
unset(compRow, getComponentKey(comp));
}
set(comp, 'hidden', true);
});
}
else {
if (!component.hasOwnProperty('clearOnHide') || component.clearOnHide) {
unset(data, path);
}
set(component, 'hidden', true);
}
} else {
conditionalComp.conditionallyHidden = false;
Expand Down
3 changes: 3 additions & 0 deletions src/process/process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { validateCustomProcessInfo, validateProcessInfo, validateServerProcessIn
import { filterProcessInfo } from "./filter";
import { normalizeProcessInfo } from "./normalize";
import { dereferenceProcessInfo } from "./dereference";
import { clearHiddenProcessInfo } from "./clearHidden";

export async function process<ProcessScope>(context: ProcessContext<ProcessScope>): Promise<ProcessScope> {
const { instances, components, data, scope, flat, processors } = context;
Expand Down Expand Up @@ -91,6 +92,7 @@ export const ProcessorMap: Record<string, ProcessorInfo<any, any>> = {
simpleConditions: simpleConditionProcessInfo,
normalize: normalizeProcessInfo,
dereference: dereferenceProcessInfo,
clearHidden: clearHiddenProcessInfo,
fetch: fetchProcessInfo,
logic: logicProcessInfo,
validate: validateProcessInfo,
Expand All @@ -113,6 +115,7 @@ export const ProcessTargets: ProcessTarget = {
calculateProcessInfo,
logicProcessInfo,
conditionProcessInfo,
clearHiddenProcessInfo,
validateProcessInfo
]
};
2 changes: 1 addition & 1 deletion src/types/BaseComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { AdvancedLogic } from "./AdvancedLogic";

export type JSONConditional = { json: RulesLogic; };
export type LegacyConditional = { show: boolean | string | null; when: string | null; eq: boolean | string };
export type SimpleConditionalConditions = { component: string; operator: string; value: any}[];
export type SimpleConditionalConditions = { component: string; operator: string; value?: any}[];
export type SimpleConditional = { show: boolean | null; conjunction: string; conditions: SimpleConditionalConditions};

export type BaseComponent = {
Expand Down
Loading