Skip to content

Commit

Permalink
merge master
Browse files Browse the repository at this point in the history
  • Loading branch information
brendanbond committed Apr 8, 2024
2 parents f62b4a5 + 46b94d3 commit 6aed425
Show file tree
Hide file tree
Showing 19 changed files with 871 additions and 58 deletions.
16 changes: 16 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
## 2.0.0-rc.24
### Changed
- FIO-8106: add default storeas value to tags
- FIO-8106: add invalidDate error translation

## 2.0.0-rc.23
### Changed
- Fix: JSONLogic validations should get same context as calculations

## 2.0.0-rc.22
### Changed
- FIO-7146: gh actions for repository
- FIO-8100: add clearhidden processor to cover logic, conditions, and custom
- FIO-8101: always process json validation even if value is falsy
- FIO-8107: correct small error in normalize processor

## 2.0.0-rc.21
### Changed
- FIO-8092: update isEmpty to isComponentDataEmpty and account for differing component data types
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@formio/core",
"version": "2.0.0-rc.21",
"version": "2.0.0-rc.24",
"description": "The core Form.io renderering framework.",
"main": "lib/index.js",
"exports": {
Expand All @@ -9,7 +9,8 @@
"./sdk": "./lib/sdk/index.js",
"./process": "./lib/process/index.js",
"./types": "./lib/types/index.js",
"./experimental": "./lib/experimental/index.js"
"./experimental": "./lib/experimental/index.js",
"./dist/formio.core.min.js": "./dist/formio.core.min.js"
},
"scripts": {
"test": "TEST=1 mocha -r ts-node/register -r tsconfig-paths/register -r mock-local-storage -r jsdom-global/register -b -t 0 'src/**/__tests__/*.test.ts'",
Expand Down
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);
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
Loading

0 comments on commit 6aed425

Please sign in to comment.