@remoteoss/json-schema-form 0.11.11-beta.0 → 0.11.11-dev.20250220174843
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +0 -6
- package/dist/index.cjs +36 -10
- package/dist/index.js +36 -10
- package/dist/standalone.js +36 -10
- package/package.json +1 -1
- package/src/tests/conditions.test.js +227 -48
- package/src/tests/createHeadlessForm.test.js +58 -3
- package/src/tests/helpers.js +56 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
#### 0.11.11-beta.0 (2025-02-20)
|
|
2
|
-
|
|
3
|
-
##### Bug Fixes
|
|
4
|
-
|
|
5
|
-
* **conditionals:** Add support to `oneOf` ([#136](https://github.com/remoteoss/json-schema-form/pull/136)) ([966cec59](https://github.com/remoteoss/json-schema-form/commit/966cec595ed2a1ff35f9d15e22acaea16cdd5113))
|
|
6
|
-
|
|
7
1
|
#### 0.11.10-beta.0 (2025-01-22)
|
|
8
2
|
|
|
9
3
|
##### Bug Fixes
|
package/dist/index.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
/*!
|
|
3
3
|
Copyright (c) 2025 Remote Technology, Inc.
|
|
4
|
-
NPM Package: @remoteoss/json-schema-form@0.11.11-
|
|
5
|
-
Generated: Thu, 20 Feb 2025
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.11.11-dev.20250220174843
|
|
5
|
+
Generated: Thu, 20 Feb 2025 17:48:57 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -101,11 +101,6 @@ function checkIfConditionMatchesProperties(node, formValues, formFields, logic)
|
|
|
101
101
|
if (typeof node.if === "boolean") {
|
|
102
102
|
return node.if;
|
|
103
103
|
}
|
|
104
|
-
if (node.if.anyOf) {
|
|
105
|
-
return node.if.anyOf.some(
|
|
106
|
-
(property) => checkIfConditionMatchesProperties({ if: property }, formValues, formFields, logic)
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
104
|
return Object.keys(node.if.properties ?? {}).every((name) => {
|
|
110
105
|
const currentProperty = node.if.properties[name];
|
|
111
106
|
const value = formValues[name];
|
|
@@ -1169,7 +1164,11 @@ function hasType(type, typeName) {
|
|
|
1169
1164
|
return Array.isArray(type) ? type.includes(typeName) : type === typeName;
|
|
1170
1165
|
}
|
|
1171
1166
|
function getField(fieldName, fields) {
|
|
1172
|
-
|
|
1167
|
+
if (Array.isArray(fields)) {
|
|
1168
|
+
return fields.find(({ name }) => name === fieldName);
|
|
1169
|
+
} else {
|
|
1170
|
+
return fields[fieldName];
|
|
1171
|
+
}
|
|
1173
1172
|
}
|
|
1174
1173
|
function validateFieldSchema(field, value, logic) {
|
|
1175
1174
|
const validator = buildYupSchema(field, {}, logic);
|
|
@@ -1383,6 +1382,25 @@ function processNode({
|
|
|
1383
1382
|
logic
|
|
1384
1383
|
});
|
|
1385
1384
|
}
|
|
1385
|
+
if (inputType === supportedTypes.GROUP_ARRAY) {
|
|
1386
|
+
const values = formValues[name];
|
|
1387
|
+
if (Array.isArray(values)) {
|
|
1388
|
+
const newFields = [];
|
|
1389
|
+
const field = getField(name, formFields);
|
|
1390
|
+
values.forEach((value) => {
|
|
1391
|
+
const fields = field.fields();
|
|
1392
|
+
processNode({
|
|
1393
|
+
node: nestedNode.items,
|
|
1394
|
+
formValues: value,
|
|
1395
|
+
formFields: fields,
|
|
1396
|
+
parentID: name,
|
|
1397
|
+
logic
|
|
1398
|
+
});
|
|
1399
|
+
newFields.push(fields);
|
|
1400
|
+
});
|
|
1401
|
+
field.dynamicFields = newFields;
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1386
1404
|
});
|
|
1387
1405
|
}
|
|
1388
1406
|
if (node["x-jsf-logic"]) {
|
|
@@ -1754,6 +1772,16 @@ function buildFieldParameters(name, fieldProperties, required = [], config = {},
|
|
|
1754
1772
|
logic
|
|
1755
1773
|
);
|
|
1756
1774
|
}
|
|
1775
|
+
if (inputType === supportedTypes.GROUP_ARRAY) {
|
|
1776
|
+
fields = () => getFieldsFromJSONSchema(
|
|
1777
|
+
fieldProperties.items,
|
|
1778
|
+
{
|
|
1779
|
+
customProperties: (0, import_get3.default)(config, `customProperties.${name}.customProperties`, {}),
|
|
1780
|
+
parentID: name
|
|
1781
|
+
},
|
|
1782
|
+
logic
|
|
1783
|
+
);
|
|
1784
|
+
}
|
|
1757
1785
|
const result = {
|
|
1758
1786
|
name,
|
|
1759
1787
|
inputType,
|
|
@@ -1847,12 +1875,10 @@ function getFieldsFromJSONSchema(scopedJsonSchema, config, logic) {
|
|
|
1847
1875
|
if (fieldParams.inputType === "group-array") {
|
|
1848
1876
|
const groupArrayItems = convertJSONSchemaPropertiesToFieldParameters(fieldParams.items);
|
|
1849
1877
|
const groupArrayFields = groupArrayItems.map((groupArrayItem) => {
|
|
1850
|
-
groupArrayItem.nameKey = groupArrayItem.name;
|
|
1851
1878
|
const customProperties = null;
|
|
1852
1879
|
const composeFn = getComposeFunctionForField(groupArrayItem, !!customProperties);
|
|
1853
1880
|
return composeFn(groupArrayItem);
|
|
1854
1881
|
});
|
|
1855
|
-
fieldParams.nameKey = fieldParams.name;
|
|
1856
1882
|
fieldParams.nthFieldGroup = {
|
|
1857
1883
|
name: fieldParams.name,
|
|
1858
1884
|
label: fieldParams.label,
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
/*!
|
|
3
3
|
Copyright (c) 2025 Remote Technology, Inc.
|
|
4
|
-
NPM Package: @remoteoss/json-schema-form@0.11.11-
|
|
5
|
-
Generated: Thu, 20 Feb 2025
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.11.11-dev.20250220174843
|
|
5
|
+
Generated: Thu, 20 Feb 2025 17:48:57 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -64,11 +64,6 @@ function checkIfConditionMatchesProperties(node, formValues, formFields, logic)
|
|
|
64
64
|
if (typeof node.if === "boolean") {
|
|
65
65
|
return node.if;
|
|
66
66
|
}
|
|
67
|
-
if (node.if.anyOf) {
|
|
68
|
-
return node.if.anyOf.some(
|
|
69
|
-
(property) => checkIfConditionMatchesProperties({ if: property }, formValues, formFields, logic)
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
67
|
return Object.keys(node.if.properties ?? {}).every((name) => {
|
|
73
68
|
const currentProperty = node.if.properties[name];
|
|
74
69
|
const value = formValues[name];
|
|
@@ -1132,7 +1127,11 @@ function hasType(type, typeName) {
|
|
|
1132
1127
|
return Array.isArray(type) ? type.includes(typeName) : type === typeName;
|
|
1133
1128
|
}
|
|
1134
1129
|
function getField(fieldName, fields) {
|
|
1135
|
-
|
|
1130
|
+
if (Array.isArray(fields)) {
|
|
1131
|
+
return fields.find(({ name }) => name === fieldName);
|
|
1132
|
+
} else {
|
|
1133
|
+
return fields[fieldName];
|
|
1134
|
+
}
|
|
1136
1135
|
}
|
|
1137
1136
|
function validateFieldSchema(field, value, logic) {
|
|
1138
1137
|
const validator = buildYupSchema(field, {}, logic);
|
|
@@ -1346,6 +1345,25 @@ function processNode({
|
|
|
1346
1345
|
logic
|
|
1347
1346
|
});
|
|
1348
1347
|
}
|
|
1348
|
+
if (inputType === supportedTypes.GROUP_ARRAY) {
|
|
1349
|
+
const values = formValues[name];
|
|
1350
|
+
if (Array.isArray(values)) {
|
|
1351
|
+
const newFields = [];
|
|
1352
|
+
const field = getField(name, formFields);
|
|
1353
|
+
values.forEach((value) => {
|
|
1354
|
+
const fields = field.fields();
|
|
1355
|
+
processNode({
|
|
1356
|
+
node: nestedNode.items,
|
|
1357
|
+
formValues: value,
|
|
1358
|
+
formFields: fields,
|
|
1359
|
+
parentID: name,
|
|
1360
|
+
logic
|
|
1361
|
+
});
|
|
1362
|
+
newFields.push(fields);
|
|
1363
|
+
});
|
|
1364
|
+
field.dynamicFields = newFields;
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1349
1367
|
});
|
|
1350
1368
|
}
|
|
1351
1369
|
if (node["x-jsf-logic"]) {
|
|
@@ -1717,6 +1735,16 @@ function buildFieldParameters(name, fieldProperties, required = [], config = {},
|
|
|
1717
1735
|
logic
|
|
1718
1736
|
);
|
|
1719
1737
|
}
|
|
1738
|
+
if (inputType === supportedTypes.GROUP_ARRAY) {
|
|
1739
|
+
fields = () => getFieldsFromJSONSchema(
|
|
1740
|
+
fieldProperties.items,
|
|
1741
|
+
{
|
|
1742
|
+
customProperties: get3(config, `customProperties.${name}.customProperties`, {}),
|
|
1743
|
+
parentID: name
|
|
1744
|
+
},
|
|
1745
|
+
logic
|
|
1746
|
+
);
|
|
1747
|
+
}
|
|
1720
1748
|
const result = {
|
|
1721
1749
|
name,
|
|
1722
1750
|
inputType,
|
|
@@ -1810,12 +1838,10 @@ function getFieldsFromJSONSchema(scopedJsonSchema, config, logic) {
|
|
|
1810
1838
|
if (fieldParams.inputType === "group-array") {
|
|
1811
1839
|
const groupArrayItems = convertJSONSchemaPropertiesToFieldParameters(fieldParams.items);
|
|
1812
1840
|
const groupArrayFields = groupArrayItems.map((groupArrayItem) => {
|
|
1813
|
-
groupArrayItem.nameKey = groupArrayItem.name;
|
|
1814
1841
|
const customProperties = null;
|
|
1815
1842
|
const composeFn = getComposeFunctionForField(groupArrayItem, !!customProperties);
|
|
1816
1843
|
return composeFn(groupArrayItem);
|
|
1817
1844
|
});
|
|
1818
|
-
fieldParams.nameKey = fieldParams.name;
|
|
1819
1845
|
fieldParams.nthFieldGroup = {
|
|
1820
1846
|
name: fieldParams.name,
|
|
1821
1847
|
label: fieldParams.label,
|
package/dist/standalone.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
/*!
|
|
3
3
|
Copyright (c) 2025 Remote Technology, Inc.
|
|
4
|
-
NPM Package: @remoteoss/json-schema-form@0.11.11-
|
|
5
|
-
Generated: Thu, 20 Feb 2025
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.11.11-dev.20250220174843
|
|
5
|
+
Generated: Thu, 20 Feb 2025 17:48:57 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -11581,11 +11581,6 @@ function checkIfConditionMatchesProperties(node, formValues, formFields, logic)
|
|
|
11581
11581
|
if (typeof node.if === "boolean") {
|
|
11582
11582
|
return node.if;
|
|
11583
11583
|
}
|
|
11584
|
-
if (node.if.anyOf) {
|
|
11585
|
-
return node.if.anyOf.some(
|
|
11586
|
-
(property2) => checkIfConditionMatchesProperties({ if: property2 }, formValues, formFields, logic)
|
|
11587
|
-
);
|
|
11588
|
-
}
|
|
11589
11584
|
return Object.keys(node.if.properties ?? {}).every((name) => {
|
|
11590
11585
|
const currentProperty = node.if.properties[name];
|
|
11591
11586
|
const value = formValues[name];
|
|
@@ -12648,7 +12643,11 @@ function hasType(type, typeName) {
|
|
|
12648
12643
|
return Array.isArray(type) ? type.includes(typeName) : type === typeName;
|
|
12649
12644
|
}
|
|
12650
12645
|
function getField(fieldName, fields) {
|
|
12651
|
-
|
|
12646
|
+
if (Array.isArray(fields)) {
|
|
12647
|
+
return fields.find(({ name }) => name === fieldName);
|
|
12648
|
+
} else {
|
|
12649
|
+
return fields[fieldName];
|
|
12650
|
+
}
|
|
12652
12651
|
}
|
|
12653
12652
|
function validateFieldSchema(field, value, logic) {
|
|
12654
12653
|
const validator = buildYupSchema(field, {}, logic);
|
|
@@ -12862,6 +12861,25 @@ function processNode({
|
|
|
12862
12861
|
logic
|
|
12863
12862
|
});
|
|
12864
12863
|
}
|
|
12864
|
+
if (inputType === supportedTypes.GROUP_ARRAY) {
|
|
12865
|
+
const values2 = formValues[name];
|
|
12866
|
+
if (Array.isArray(values2)) {
|
|
12867
|
+
const newFields = [];
|
|
12868
|
+
const field = getField(name, formFields);
|
|
12869
|
+
values2.forEach((value) => {
|
|
12870
|
+
const fields = field.fields();
|
|
12871
|
+
processNode({
|
|
12872
|
+
node: nestedNode.items,
|
|
12873
|
+
formValues: value,
|
|
12874
|
+
formFields: fields,
|
|
12875
|
+
parentID: name,
|
|
12876
|
+
logic
|
|
12877
|
+
});
|
|
12878
|
+
newFields.push(fields);
|
|
12879
|
+
});
|
|
12880
|
+
field.dynamicFields = newFields;
|
|
12881
|
+
}
|
|
12882
|
+
}
|
|
12865
12883
|
});
|
|
12866
12884
|
}
|
|
12867
12885
|
if (node["x-jsf-logic"]) {
|
|
@@ -13233,6 +13251,16 @@ function buildFieldParameters(name, fieldProperties, required2 = [], config = {}
|
|
|
13233
13251
|
logic
|
|
13234
13252
|
);
|
|
13235
13253
|
}
|
|
13254
|
+
if (inputType === supportedTypes.GROUP_ARRAY) {
|
|
13255
|
+
fields = () => getFieldsFromJSONSchema(
|
|
13256
|
+
fieldProperties.items,
|
|
13257
|
+
{
|
|
13258
|
+
customProperties: (0, import_get4.default)(config, `customProperties.${name}.customProperties`, {}),
|
|
13259
|
+
parentID: name
|
|
13260
|
+
},
|
|
13261
|
+
logic
|
|
13262
|
+
);
|
|
13263
|
+
}
|
|
13236
13264
|
const result = {
|
|
13237
13265
|
name,
|
|
13238
13266
|
inputType,
|
|
@@ -13326,12 +13354,10 @@ function getFieldsFromJSONSchema(scopedJsonSchema, config, logic) {
|
|
|
13326
13354
|
if (fieldParams.inputType === "group-array") {
|
|
13327
13355
|
const groupArrayItems = convertJSONSchemaPropertiesToFieldParameters(fieldParams.items);
|
|
13328
13356
|
const groupArrayFields = groupArrayItems.map((groupArrayItem) => {
|
|
13329
|
-
groupArrayItem.nameKey = groupArrayItem.name;
|
|
13330
13357
|
const customProperties = null;
|
|
13331
13358
|
const composeFn = getComposeFunctionForField(groupArrayItem, !!customProperties);
|
|
13332
13359
|
return composeFn(groupArrayItem);
|
|
13333
13360
|
});
|
|
13334
|
-
fieldParams.nameKey = fieldParams.name;
|
|
13335
13361
|
fieldParams.nthFieldGroup = {
|
|
13336
13362
|
name: fieldParams.name,
|
|
13337
13363
|
label: fieldParams.label,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remoteoss/json-schema-form",
|
|
3
|
-
"version": "0.11.11-
|
|
3
|
+
"version": "0.11.11-dev.20250220174843",
|
|
4
4
|
"description": "Headless UI form powered by JSON Schemas",
|
|
5
5
|
"author": "Remote.com <engineering@remote.com> (https://remote.com/)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -422,6 +422,233 @@ describe('Conditional attributes updated', () => {
|
|
|
422
422
|
handleValidation({ is_full_time: 'no' });
|
|
423
423
|
expect(fields[1].visibilityCondition).toEqual(expect.any(Function));
|
|
424
424
|
});
|
|
425
|
+
|
|
426
|
+
it('Group array nested condition', () => {
|
|
427
|
+
const { fields, handleValidation } = createHeadlessForm({
|
|
428
|
+
type: 'object',
|
|
429
|
+
additionalProperties: false,
|
|
430
|
+
properties: {
|
|
431
|
+
companies: {
|
|
432
|
+
type: 'array',
|
|
433
|
+
'x-jsf-presentation': {
|
|
434
|
+
inputType: 'group-array',
|
|
435
|
+
},
|
|
436
|
+
items: {
|
|
437
|
+
type: 'object',
|
|
438
|
+
properties: {
|
|
439
|
+
company: {
|
|
440
|
+
type: 'string',
|
|
441
|
+
oneOf: [
|
|
442
|
+
{
|
|
443
|
+
title: 'A',
|
|
444
|
+
const: 'A',
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
title: 'B',
|
|
448
|
+
const: 'B',
|
|
449
|
+
},
|
|
450
|
+
],
|
|
451
|
+
'x-jsf-presentation': {
|
|
452
|
+
inputType: 'select',
|
|
453
|
+
},
|
|
454
|
+
},
|
|
455
|
+
role: {
|
|
456
|
+
title: 'Role',
|
|
457
|
+
oneOf: [],
|
|
458
|
+
'x-jsf-presentation': {
|
|
459
|
+
inputType: 'select',
|
|
460
|
+
},
|
|
461
|
+
},
|
|
462
|
+
},
|
|
463
|
+
allOf: [
|
|
464
|
+
{
|
|
465
|
+
if: {
|
|
466
|
+
properties: {
|
|
467
|
+
company: {
|
|
468
|
+
const: 'A',
|
|
469
|
+
},
|
|
470
|
+
},
|
|
471
|
+
required: ['company'],
|
|
472
|
+
},
|
|
473
|
+
then: {
|
|
474
|
+
properties: {
|
|
475
|
+
role: {
|
|
476
|
+
oneOf: [
|
|
477
|
+
{
|
|
478
|
+
title: 'adminA',
|
|
479
|
+
const: 'adminA',
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
title: 'userA',
|
|
483
|
+
const: 'userA',
|
|
484
|
+
},
|
|
485
|
+
],
|
|
486
|
+
'x-jsf-presentation': {
|
|
487
|
+
inputType: 'select',
|
|
488
|
+
},
|
|
489
|
+
},
|
|
490
|
+
},
|
|
491
|
+
required: ['role'],
|
|
492
|
+
},
|
|
493
|
+
},
|
|
494
|
+
{
|
|
495
|
+
if: {
|
|
496
|
+
properties: {
|
|
497
|
+
company: {
|
|
498
|
+
const: 'B',
|
|
499
|
+
},
|
|
500
|
+
},
|
|
501
|
+
required: ['company'],
|
|
502
|
+
},
|
|
503
|
+
then: {
|
|
504
|
+
properties: {
|
|
505
|
+
role: {
|
|
506
|
+
oneOf: [
|
|
507
|
+
{
|
|
508
|
+
title: 'adminB',
|
|
509
|
+
const: 'adminB',
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
title: 'userB',
|
|
513
|
+
const: 'userB',
|
|
514
|
+
},
|
|
515
|
+
],
|
|
516
|
+
'x-jsf-presentation': {
|
|
517
|
+
inputType: 'select',
|
|
518
|
+
},
|
|
519
|
+
},
|
|
520
|
+
},
|
|
521
|
+
required: ['role'],
|
|
522
|
+
},
|
|
523
|
+
},
|
|
524
|
+
],
|
|
525
|
+
required: ['company', 'role'],
|
|
526
|
+
},
|
|
527
|
+
},
|
|
528
|
+
},
|
|
529
|
+
required: ['companies'],
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
handleValidation({ companies: [{ company: 'A' }, { company: 'B' }] });
|
|
533
|
+
expect(fields[0].dynamicFields[0][1].options).toEqual([
|
|
534
|
+
{ label: 'adminA', value: 'adminA' },
|
|
535
|
+
{ label: 'userA', value: 'userA' },
|
|
536
|
+
]);
|
|
537
|
+
expect(fields[0].dynamicFields[1][1].options).toEqual([
|
|
538
|
+
{ label: 'adminB', value: 'adminB' },
|
|
539
|
+
{ label: 'userB', value: 'userB' },
|
|
540
|
+
]);
|
|
541
|
+
handleValidation({ companies: [] });
|
|
542
|
+
expect(fields[0].dynamicFields).toEqual([]);
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
it('select multiple conditions', () => {
|
|
546
|
+
const { fields, handleValidation } = createHeadlessForm({
|
|
547
|
+
type: 'object',
|
|
548
|
+
additionalProperties: false,
|
|
549
|
+
properties: {
|
|
550
|
+
company: {
|
|
551
|
+
title: 'Select Company',
|
|
552
|
+
type: 'string',
|
|
553
|
+
description: 'Choose a company',
|
|
554
|
+
oneOf: [
|
|
555
|
+
{
|
|
556
|
+
title: 'A',
|
|
557
|
+
const: 'A',
|
|
558
|
+
},
|
|
559
|
+
{
|
|
560
|
+
title: 'B',
|
|
561
|
+
const: 'B',
|
|
562
|
+
},
|
|
563
|
+
],
|
|
564
|
+
'x-jsf-presentation': {
|
|
565
|
+
inputType: 'select',
|
|
566
|
+
},
|
|
567
|
+
},
|
|
568
|
+
role: {
|
|
569
|
+
title: 'Role',
|
|
570
|
+
oneOf: [],
|
|
571
|
+
'x-jsf-presentation': {
|
|
572
|
+
inputType: 'select',
|
|
573
|
+
},
|
|
574
|
+
},
|
|
575
|
+
},
|
|
576
|
+
allOf: [
|
|
577
|
+
{
|
|
578
|
+
if: {
|
|
579
|
+
properties: {
|
|
580
|
+
company: {
|
|
581
|
+
const: 'A',
|
|
582
|
+
},
|
|
583
|
+
},
|
|
584
|
+
required: ['company'],
|
|
585
|
+
},
|
|
586
|
+
then: {
|
|
587
|
+
properties: {
|
|
588
|
+
role: {
|
|
589
|
+
oneOf: [
|
|
590
|
+
{
|
|
591
|
+
title: 'adminA',
|
|
592
|
+
const: 'adminA',
|
|
593
|
+
},
|
|
594
|
+
{
|
|
595
|
+
title: 'userA',
|
|
596
|
+
const: 'userA',
|
|
597
|
+
},
|
|
598
|
+
],
|
|
599
|
+
'x-jsf-presentation': {
|
|
600
|
+
inputType: 'select',
|
|
601
|
+
},
|
|
602
|
+
},
|
|
603
|
+
},
|
|
604
|
+
required: ['role'],
|
|
605
|
+
},
|
|
606
|
+
},
|
|
607
|
+
{
|
|
608
|
+
if: {
|
|
609
|
+
properties: {
|
|
610
|
+
company: {
|
|
611
|
+
const: 'B',
|
|
612
|
+
},
|
|
613
|
+
},
|
|
614
|
+
required: ['company'],
|
|
615
|
+
},
|
|
616
|
+
then: {
|
|
617
|
+
properties: {
|
|
618
|
+
role: {
|
|
619
|
+
oneOf: [
|
|
620
|
+
{
|
|
621
|
+
title: 'adminB',
|
|
622
|
+
const: 'adminB',
|
|
623
|
+
},
|
|
624
|
+
{
|
|
625
|
+
title: 'userB',
|
|
626
|
+
const: 'userB',
|
|
627
|
+
},
|
|
628
|
+
],
|
|
629
|
+
'x-jsf-presentation': {
|
|
630
|
+
inputType: 'select',
|
|
631
|
+
},
|
|
632
|
+
},
|
|
633
|
+
},
|
|
634
|
+
required: ['role'],
|
|
635
|
+
},
|
|
636
|
+
},
|
|
637
|
+
],
|
|
638
|
+
required: ['company', 'role'],
|
|
639
|
+
});
|
|
640
|
+
|
|
641
|
+
handleValidation({ company: 'A' });
|
|
642
|
+
expect(fields[1].options).toEqual([
|
|
643
|
+
{ label: 'adminA', value: 'adminA' },
|
|
644
|
+
{ label: 'userA', value: 'userA' },
|
|
645
|
+
]);
|
|
646
|
+
handleValidation({ company: 'B' });
|
|
647
|
+
expect(fields[1].options).toEqual([
|
|
648
|
+
{ label: 'adminB', value: 'adminB' },
|
|
649
|
+
{ label: 'userB', value: 'userB' },
|
|
650
|
+
]);
|
|
651
|
+
});
|
|
425
652
|
});
|
|
426
653
|
|
|
427
654
|
describe('Conditional with a minimum value check', () => {
|
|
@@ -548,54 +775,6 @@ describe('Conditional with literal booleans', () => {
|
|
|
548
775
|
});
|
|
549
776
|
});
|
|
550
777
|
|
|
551
|
-
describe('Conditional with anyOf', () => {
|
|
552
|
-
const schema = {
|
|
553
|
-
additionalProperties: false,
|
|
554
|
-
type: 'object',
|
|
555
|
-
properties: {
|
|
556
|
-
field_a: { type: 'string' },
|
|
557
|
-
field_b: { type: 'string' },
|
|
558
|
-
field_c: { type: 'string' },
|
|
559
|
-
},
|
|
560
|
-
allOf: [
|
|
561
|
-
{
|
|
562
|
-
if: {
|
|
563
|
-
anyOf: [
|
|
564
|
-
{ properties: { field_a: { const: '1' } }, required: ['field_a'] },
|
|
565
|
-
{ properties: { field_b: { const: '2' } }, required: ['field_b'] },
|
|
566
|
-
],
|
|
567
|
-
},
|
|
568
|
-
then: {
|
|
569
|
-
required: ['field_c'],
|
|
570
|
-
},
|
|
571
|
-
else: {
|
|
572
|
-
properties: {
|
|
573
|
-
field_c: false,
|
|
574
|
-
},
|
|
575
|
-
},
|
|
576
|
-
},
|
|
577
|
-
],
|
|
578
|
-
};
|
|
579
|
-
|
|
580
|
-
it('handles true case', () => {
|
|
581
|
-
const { fields, handleValidation } = createHeadlessForm(schema, { strictInputType: false });
|
|
582
|
-
|
|
583
|
-
expect(fields[2].isVisible).toBe(false);
|
|
584
|
-
expect(handleValidation({ field_a: 'x', field_b: '2' }).formErrors).toEqual({
|
|
585
|
-
field_c: 'Required field',
|
|
586
|
-
});
|
|
587
|
-
expect(fields[2].isVisible).toBe(true);
|
|
588
|
-
});
|
|
589
|
-
|
|
590
|
-
it('handles false case', () => {
|
|
591
|
-
const { fields, handleValidation } = createHeadlessForm(schema, { strictInputType: false });
|
|
592
|
-
|
|
593
|
-
expect(fields[2].isVisible).toBe(false);
|
|
594
|
-
expect(handleValidation({ field_a: 'x', field_b: 'x' }).formErrors).toBeUndefined();
|
|
595
|
-
expect(fields[2].isVisible).toBe(false);
|
|
596
|
-
});
|
|
597
|
-
});
|
|
598
|
-
|
|
599
778
|
describe('Conditionals - bugs and code-smells', () => {
|
|
600
779
|
// Why do we have these bugs?
|
|
601
780
|
// To be honest we never realized it much later later.
|
|
@@ -63,6 +63,7 @@ import {
|
|
|
63
63
|
schemaForErrorMessageSpecificity,
|
|
64
64
|
jsfConfigForErrorMessageSpecificity,
|
|
65
65
|
schemaInputTypeFile,
|
|
66
|
+
nestedGroupArrayForm,
|
|
66
67
|
} from './helpers';
|
|
67
68
|
import { mockConsole, restoreConsoleAndEnsureItWasNotCalled } from './testUtils';
|
|
68
69
|
import { createHeadlessForm } from '@/createHeadlessForm';
|
|
@@ -1604,7 +1605,6 @@ describe('createHeadlessForm', () => {
|
|
|
1604
1605
|
type: 'text',
|
|
1605
1606
|
description: 'Enter your child’s full name',
|
|
1606
1607
|
maxLength: 255,
|
|
1607
|
-
nameKey: 'full_name',
|
|
1608
1608
|
label: 'Child Full Name',
|
|
1609
1609
|
name: 'full_name',
|
|
1610
1610
|
required: true,
|
|
@@ -1616,7 +1616,6 @@ describe('createHeadlessForm', () => {
|
|
|
1616
1616
|
required: true,
|
|
1617
1617
|
description: 'Enter your child’s date of birth',
|
|
1618
1618
|
maxLength: 255,
|
|
1619
|
-
nameKey: 'birthdate',
|
|
1620
1619
|
},
|
|
1621
1620
|
{
|
|
1622
1621
|
type: 'radio',
|
|
@@ -1635,7 +1634,6 @@ describe('createHeadlessForm', () => {
|
|
|
1635
1634
|
required: true,
|
|
1636
1635
|
description:
|
|
1637
1636
|
'We know sex is non-binary but for insurance and payroll purposes, we need to collect this information.',
|
|
1638
|
-
nameKey: 'sex',
|
|
1639
1637
|
},
|
|
1640
1638
|
]);
|
|
1641
1639
|
});
|
|
@@ -1737,6 +1735,63 @@ describe('createHeadlessForm', () => {
|
|
|
1737
1735
|
});
|
|
1738
1736
|
});
|
|
1739
1737
|
|
|
1738
|
+
it('nested "group-array" fields', () => {
|
|
1739
|
+
const result = createHeadlessForm({
|
|
1740
|
+
properties: {
|
|
1741
|
+
nestedGroupArray: nestedGroupArrayForm,
|
|
1742
|
+
},
|
|
1743
|
+
});
|
|
1744
|
+
|
|
1745
|
+
expect(result.fields[0]).toMatchObject({
|
|
1746
|
+
label: 'Parent object',
|
|
1747
|
+
name: 'nestedGroupArray',
|
|
1748
|
+
required: false,
|
|
1749
|
+
type: 'group-array',
|
|
1750
|
+
inputType: 'group-array',
|
|
1751
|
+
jsonType: 'array',
|
|
1752
|
+
fields: expect.any(Function),
|
|
1753
|
+
});
|
|
1754
|
+
|
|
1755
|
+
expect(result.fields[0].fields()).toMatchObject([
|
|
1756
|
+
{
|
|
1757
|
+
type: 'text',
|
|
1758
|
+
description: 'Simple text field',
|
|
1759
|
+
maxLength: 255,
|
|
1760
|
+
label: 'Outer Field',
|
|
1761
|
+
name: 'notNested',
|
|
1762
|
+
required: true,
|
|
1763
|
+
},
|
|
1764
|
+
{
|
|
1765
|
+
label: 'Nested group-array',
|
|
1766
|
+
name: 'nested',
|
|
1767
|
+
required: true,
|
|
1768
|
+
type: 'group-array',
|
|
1769
|
+
inputType: 'group-array',
|
|
1770
|
+
jsonType: 'array',
|
|
1771
|
+
fields: expect.any(Function),
|
|
1772
|
+
},
|
|
1773
|
+
]);
|
|
1774
|
+
|
|
1775
|
+
expect(result.fields[0].fields()[1].fields()).toMatchObject([
|
|
1776
|
+
{
|
|
1777
|
+
type: 'text',
|
|
1778
|
+
description: 'First nested text field',
|
|
1779
|
+
maxLength: 255,
|
|
1780
|
+
label: 'Inner Field 1',
|
|
1781
|
+
name: 'nestedField1',
|
|
1782
|
+
required: true,
|
|
1783
|
+
},
|
|
1784
|
+
{
|
|
1785
|
+
type: 'text',
|
|
1786
|
+
description: 'Second nested text field',
|
|
1787
|
+
maxLength: 255,
|
|
1788
|
+
label: 'Inner Field 2',
|
|
1789
|
+
name: 'nestedField2',
|
|
1790
|
+
required: true,
|
|
1791
|
+
},
|
|
1792
|
+
]);
|
|
1793
|
+
});
|
|
1794
|
+
|
|
1740
1795
|
it('can pass custom field attributes', () => {
|
|
1741
1796
|
const result = createHeadlessForm(
|
|
1742
1797
|
{
|
package/src/tests/helpers.js
CHANGED
|
@@ -2327,3 +2327,59 @@ export const schemaWithCustomValidationsAndConditionals = {
|
|
|
2327
2327
|
},
|
|
2328
2328
|
],
|
|
2329
2329
|
};
|
|
2330
|
+
|
|
2331
|
+
export const nestedGroupArrayForm = {
|
|
2332
|
+
items: {
|
|
2333
|
+
properties: {
|
|
2334
|
+
notNested: {
|
|
2335
|
+
description: 'Simple text field',
|
|
2336
|
+
'x-jsf-presentation': {
|
|
2337
|
+
inputType: 'text',
|
|
2338
|
+
},
|
|
2339
|
+
title: 'Outer Field',
|
|
2340
|
+
type: 'string',
|
|
2341
|
+
maxLength: 255,
|
|
2342
|
+
},
|
|
2343
|
+
nested: {
|
|
2344
|
+
items: {
|
|
2345
|
+
properties: {
|
|
2346
|
+
nestedField1: {
|
|
2347
|
+
description: 'First nested text field',
|
|
2348
|
+
'x-jsf-presentation': {
|
|
2349
|
+
inputType: 'text',
|
|
2350
|
+
},
|
|
2351
|
+
title: 'Inner Field 1',
|
|
2352
|
+
type: 'string',
|
|
2353
|
+
maxLength: 255,
|
|
2354
|
+
},
|
|
2355
|
+
nestedField2: {
|
|
2356
|
+
description: 'Second nested text field',
|
|
2357
|
+
'x-jsf-presentation': {
|
|
2358
|
+
inputType: 'text',
|
|
2359
|
+
},
|
|
2360
|
+
title: 'Inner Field 2',
|
|
2361
|
+
type: 'string',
|
|
2362
|
+
maxLength: 255,
|
|
2363
|
+
},
|
|
2364
|
+
},
|
|
2365
|
+
'x-jsf-order': ['nestedField1', 'nestedField2'],
|
|
2366
|
+
required: ['nestedField1', 'nestedField2'],
|
|
2367
|
+
type: 'object',
|
|
2368
|
+
},
|
|
2369
|
+
'x-jsf-presentation': {
|
|
2370
|
+
inputType: 'group-array',
|
|
2371
|
+
},
|
|
2372
|
+
title: 'Nested group-array',
|
|
2373
|
+
type: 'array',
|
|
2374
|
+
},
|
|
2375
|
+
},
|
|
2376
|
+
'x-jsf-order': ['notNested', 'nested'],
|
|
2377
|
+
required: ['notNested', 'nested'],
|
|
2378
|
+
type: 'object',
|
|
2379
|
+
},
|
|
2380
|
+
'x-jsf-presentation': {
|
|
2381
|
+
inputType: 'group-array',
|
|
2382
|
+
},
|
|
2383
|
+
title: 'Parent object',
|
|
2384
|
+
type: 'array',
|
|
2385
|
+
};
|