@remoteoss/json-schema-form 0.11.11-dev.20250220174843 → 0.11.12-dev.20250313084704
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 +6 -0
- package/dist/index.cjs +14 -37
- package/dist/index.js +14 -37
- package/dist/standalone.js +14 -37
- package/package.json +1 -1
- package/src/tests/conditions.test.js +48 -227
- package/src/tests/createHeadlessForm.test.js +25 -58
- package/src/tests/helpers.js +16 -51
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
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
|
+
|
|
1
7
|
#### 0.11.10-beta.0 (2025-01-22)
|
|
2
8
|
|
|
3
9
|
##### 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.
|
|
5
|
-
Generated: Thu,
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.11.12-dev.20250313084704
|
|
5
|
+
Generated: Thu, 13 Mar 2025 08:47:14 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -101,6 +101,11 @@ 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
|
+
}
|
|
104
109
|
return Object.keys(node.if.properties ?? {}).every((name) => {
|
|
105
110
|
const currentProperty = node.if.properties[name];
|
|
106
111
|
const value = formValues[name];
|
|
@@ -608,6 +613,8 @@ var getYupSchema = ({ inputType, ...field }) => {
|
|
|
608
613
|
switch (type) {
|
|
609
614
|
case "number":
|
|
610
615
|
return yupSchemas.radioOrSelectNumber(optionValues);
|
|
616
|
+
case "integer":
|
|
617
|
+
return yupSchemas.radioOrSelectNumber(optionValues);
|
|
611
618
|
case "boolean":
|
|
612
619
|
return yupSchemas.radioOrSelectBoolean(optionValues);
|
|
613
620
|
default:
|
|
@@ -768,7 +775,8 @@ function buildYupSchema(field, config, logic) {
|
|
|
768
775
|
if (inputType === supportedTypes.FILE) {
|
|
769
776
|
validators.push(withFile);
|
|
770
777
|
}
|
|
771
|
-
|
|
778
|
+
const hasOptions = field.options?.length > 0;
|
|
779
|
+
if (jsonType === "integer" && !hasOptions) {
|
|
772
780
|
validators.push(withInteger);
|
|
773
781
|
}
|
|
774
782
|
if (typeof propertyFields.minimum !== "undefined") {
|
|
@@ -1164,11 +1172,7 @@ function hasType(type, typeName) {
|
|
|
1164
1172
|
return Array.isArray(type) ? type.includes(typeName) : type === typeName;
|
|
1165
1173
|
}
|
|
1166
1174
|
function getField(fieldName, fields) {
|
|
1167
|
-
|
|
1168
|
-
return fields.find(({ name }) => name === fieldName);
|
|
1169
|
-
} else {
|
|
1170
|
-
return fields[fieldName];
|
|
1171
|
-
}
|
|
1175
|
+
return fields.find(({ name }) => name === fieldName);
|
|
1172
1176
|
}
|
|
1173
1177
|
function validateFieldSchema(field, value, logic) {
|
|
1174
1178
|
const validator = buildYupSchema(field, {}, logic);
|
|
@@ -1382,25 +1386,6 @@ function processNode({
|
|
|
1382
1386
|
logic
|
|
1383
1387
|
});
|
|
1384
1388
|
}
|
|
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
|
-
}
|
|
1404
1389
|
});
|
|
1405
1390
|
}
|
|
1406
1391
|
if (node["x-jsf-logic"]) {
|
|
@@ -1772,16 +1757,6 @@ function buildFieldParameters(name, fieldProperties, required = [], config = {},
|
|
|
1772
1757
|
logic
|
|
1773
1758
|
);
|
|
1774
1759
|
}
|
|
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
|
-
}
|
|
1785
1760
|
const result = {
|
|
1786
1761
|
name,
|
|
1787
1762
|
inputType,
|
|
@@ -1875,10 +1850,12 @@ function getFieldsFromJSONSchema(scopedJsonSchema, config, logic) {
|
|
|
1875
1850
|
if (fieldParams.inputType === "group-array") {
|
|
1876
1851
|
const groupArrayItems = convertJSONSchemaPropertiesToFieldParameters(fieldParams.items);
|
|
1877
1852
|
const groupArrayFields = groupArrayItems.map((groupArrayItem) => {
|
|
1853
|
+
groupArrayItem.nameKey = groupArrayItem.name;
|
|
1878
1854
|
const customProperties = null;
|
|
1879
1855
|
const composeFn = getComposeFunctionForField(groupArrayItem, !!customProperties);
|
|
1880
1856
|
return composeFn(groupArrayItem);
|
|
1881
1857
|
});
|
|
1858
|
+
fieldParams.nameKey = fieldParams.name;
|
|
1882
1859
|
fieldParams.nthFieldGroup = {
|
|
1883
1860
|
name: fieldParams.name,
|
|
1884
1861
|
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.
|
|
5
|
-
Generated: Thu,
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.11.12-dev.20250313084704
|
|
5
|
+
Generated: Thu, 13 Mar 2025 08:47:14 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -64,6 +64,11 @@ 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
|
+
}
|
|
67
72
|
return Object.keys(node.if.properties ?? {}).every((name) => {
|
|
68
73
|
const currentProperty = node.if.properties[name];
|
|
69
74
|
const value = formValues[name];
|
|
@@ -571,6 +576,8 @@ var getYupSchema = ({ inputType, ...field }) => {
|
|
|
571
576
|
switch (type) {
|
|
572
577
|
case "number":
|
|
573
578
|
return yupSchemas.radioOrSelectNumber(optionValues);
|
|
579
|
+
case "integer":
|
|
580
|
+
return yupSchemas.radioOrSelectNumber(optionValues);
|
|
574
581
|
case "boolean":
|
|
575
582
|
return yupSchemas.radioOrSelectBoolean(optionValues);
|
|
576
583
|
default:
|
|
@@ -731,7 +738,8 @@ function buildYupSchema(field, config, logic) {
|
|
|
731
738
|
if (inputType === supportedTypes.FILE) {
|
|
732
739
|
validators.push(withFile);
|
|
733
740
|
}
|
|
734
|
-
|
|
741
|
+
const hasOptions = field.options?.length > 0;
|
|
742
|
+
if (jsonType === "integer" && !hasOptions) {
|
|
735
743
|
validators.push(withInteger);
|
|
736
744
|
}
|
|
737
745
|
if (typeof propertyFields.minimum !== "undefined") {
|
|
@@ -1127,11 +1135,7 @@ function hasType(type, typeName) {
|
|
|
1127
1135
|
return Array.isArray(type) ? type.includes(typeName) : type === typeName;
|
|
1128
1136
|
}
|
|
1129
1137
|
function getField(fieldName, fields) {
|
|
1130
|
-
|
|
1131
|
-
return fields.find(({ name }) => name === fieldName);
|
|
1132
|
-
} else {
|
|
1133
|
-
return fields[fieldName];
|
|
1134
|
-
}
|
|
1138
|
+
return fields.find(({ name }) => name === fieldName);
|
|
1135
1139
|
}
|
|
1136
1140
|
function validateFieldSchema(field, value, logic) {
|
|
1137
1141
|
const validator = buildYupSchema(field, {}, logic);
|
|
@@ -1345,25 +1349,6 @@ function processNode({
|
|
|
1345
1349
|
logic
|
|
1346
1350
|
});
|
|
1347
1351
|
}
|
|
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
|
-
}
|
|
1367
1352
|
});
|
|
1368
1353
|
}
|
|
1369
1354
|
if (node["x-jsf-logic"]) {
|
|
@@ -1735,16 +1720,6 @@ function buildFieldParameters(name, fieldProperties, required = [], config = {},
|
|
|
1735
1720
|
logic
|
|
1736
1721
|
);
|
|
1737
1722
|
}
|
|
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
|
-
}
|
|
1748
1723
|
const result = {
|
|
1749
1724
|
name,
|
|
1750
1725
|
inputType,
|
|
@@ -1838,10 +1813,12 @@ function getFieldsFromJSONSchema(scopedJsonSchema, config, logic) {
|
|
|
1838
1813
|
if (fieldParams.inputType === "group-array") {
|
|
1839
1814
|
const groupArrayItems = convertJSONSchemaPropertiesToFieldParameters(fieldParams.items);
|
|
1840
1815
|
const groupArrayFields = groupArrayItems.map((groupArrayItem) => {
|
|
1816
|
+
groupArrayItem.nameKey = groupArrayItem.name;
|
|
1841
1817
|
const customProperties = null;
|
|
1842
1818
|
const composeFn = getComposeFunctionForField(groupArrayItem, !!customProperties);
|
|
1843
1819
|
return composeFn(groupArrayItem);
|
|
1844
1820
|
});
|
|
1821
|
+
fieldParams.nameKey = fieldParams.name;
|
|
1845
1822
|
fieldParams.nthFieldGroup = {
|
|
1846
1823
|
name: fieldParams.name,
|
|
1847
1824
|
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.
|
|
5
|
-
Generated: Thu,
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.11.12-dev.20250313084704
|
|
5
|
+
Generated: Thu, 13 Mar 2025 08:47:14 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -11581,6 +11581,11 @@ 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
|
+
}
|
|
11584
11589
|
return Object.keys(node.if.properties ?? {}).every((name) => {
|
|
11585
11590
|
const currentProperty = node.if.properties[name];
|
|
11586
11591
|
const value = formValues[name];
|
|
@@ -12087,6 +12092,8 @@ var getYupSchema = ({ inputType, ...field }) => {
|
|
|
12087
12092
|
switch (type) {
|
|
12088
12093
|
case "number":
|
|
12089
12094
|
return yupSchemas.radioOrSelectNumber(optionValues);
|
|
12095
|
+
case "integer":
|
|
12096
|
+
return yupSchemas.radioOrSelectNumber(optionValues);
|
|
12090
12097
|
case "boolean":
|
|
12091
12098
|
return yupSchemas.radioOrSelectBoolean(optionValues);
|
|
12092
12099
|
default:
|
|
@@ -12247,7 +12254,8 @@ function buildYupSchema(field, config, logic) {
|
|
|
12247
12254
|
if (inputType === supportedTypes.FILE) {
|
|
12248
12255
|
validators.push(withFile);
|
|
12249
12256
|
}
|
|
12250
|
-
|
|
12257
|
+
const hasOptions = field.options?.length > 0;
|
|
12258
|
+
if (jsonType === "integer" && !hasOptions) {
|
|
12251
12259
|
validators.push(withInteger);
|
|
12252
12260
|
}
|
|
12253
12261
|
if (typeof propertyFields.minimum !== "undefined") {
|
|
@@ -12643,11 +12651,7 @@ function hasType(type, typeName) {
|
|
|
12643
12651
|
return Array.isArray(type) ? type.includes(typeName) : type === typeName;
|
|
12644
12652
|
}
|
|
12645
12653
|
function getField(fieldName, fields) {
|
|
12646
|
-
|
|
12647
|
-
return fields.find(({ name }) => name === fieldName);
|
|
12648
|
-
} else {
|
|
12649
|
-
return fields[fieldName];
|
|
12650
|
-
}
|
|
12654
|
+
return fields.find(({ name }) => name === fieldName);
|
|
12651
12655
|
}
|
|
12652
12656
|
function validateFieldSchema(field, value, logic) {
|
|
12653
12657
|
const validator = buildYupSchema(field, {}, logic);
|
|
@@ -12861,25 +12865,6 @@ function processNode({
|
|
|
12861
12865
|
logic
|
|
12862
12866
|
});
|
|
12863
12867
|
}
|
|
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
|
-
}
|
|
12883
12868
|
});
|
|
12884
12869
|
}
|
|
12885
12870
|
if (node["x-jsf-logic"]) {
|
|
@@ -13251,16 +13236,6 @@ function buildFieldParameters(name, fieldProperties, required2 = [], config = {}
|
|
|
13251
13236
|
logic
|
|
13252
13237
|
);
|
|
13253
13238
|
}
|
|
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
|
-
}
|
|
13264
13239
|
const result = {
|
|
13265
13240
|
name,
|
|
13266
13241
|
inputType,
|
|
@@ -13354,10 +13329,12 @@ function getFieldsFromJSONSchema(scopedJsonSchema, config, logic) {
|
|
|
13354
13329
|
if (fieldParams.inputType === "group-array") {
|
|
13355
13330
|
const groupArrayItems = convertJSONSchemaPropertiesToFieldParameters(fieldParams.items);
|
|
13356
13331
|
const groupArrayFields = groupArrayItems.map((groupArrayItem) => {
|
|
13332
|
+
groupArrayItem.nameKey = groupArrayItem.name;
|
|
13357
13333
|
const customProperties = null;
|
|
13358
13334
|
const composeFn = getComposeFunctionForField(groupArrayItem, !!customProperties);
|
|
13359
13335
|
return composeFn(groupArrayItem);
|
|
13360
13336
|
});
|
|
13337
|
+
fieldParams.nameKey = fieldParams.name;
|
|
13361
13338
|
fieldParams.nthFieldGroup = {
|
|
13362
13339
|
name: fieldParams.name,
|
|
13363
13340
|
label: fieldParams.label,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remoteoss/json-schema-form",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.12-dev.20250313084704",
|
|
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,233 +422,6 @@ 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
|
-
});
|
|
652
425
|
});
|
|
653
426
|
|
|
654
427
|
describe('Conditional with a minimum value check', () => {
|
|
@@ -775,6 +548,54 @@ describe('Conditional with literal booleans', () => {
|
|
|
775
548
|
});
|
|
776
549
|
});
|
|
777
550
|
|
|
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
|
+
|
|
778
599
|
describe('Conditionals - bugs and code-smells', () => {
|
|
779
600
|
// Why do we have these bugs?
|
|
780
601
|
// To be honest we never realized it much later later.
|
|
@@ -63,7 +63,7 @@ import {
|
|
|
63
63
|
schemaForErrorMessageSpecificity,
|
|
64
64
|
jsfConfigForErrorMessageSpecificity,
|
|
65
65
|
schemaInputTypeFile,
|
|
66
|
-
|
|
66
|
+
schemaWithSelectInteger,
|
|
67
67
|
} from './helpers';
|
|
68
68
|
import { mockConsole, restoreConsoleAndEnsureItWasNotCalled } from './testUtils';
|
|
69
69
|
import { createHeadlessForm } from '@/createHeadlessForm';
|
|
@@ -658,6 +658,27 @@ describe('createHeadlessForm', () => {
|
|
|
658
658
|
],
|
|
659
659
|
});
|
|
660
660
|
});
|
|
661
|
+
|
|
662
|
+
it('supports "select" field with integer values', async () => {
|
|
663
|
+
const { handleValidation } = createHeadlessForm(schemaWithSelectInteger);
|
|
664
|
+
const validateForm = (vals) => friendlyError(handleValidation(vals));
|
|
665
|
+
|
|
666
|
+
// Check for invalid option
|
|
667
|
+
expect(
|
|
668
|
+
validateForm({
|
|
669
|
+
account_type: 4,
|
|
670
|
+
})
|
|
671
|
+
).toEqual({
|
|
672
|
+
account_type: 'The option 4 is not valid.',
|
|
673
|
+
});
|
|
674
|
+
|
|
675
|
+
// Check for valid option
|
|
676
|
+
expect(
|
|
677
|
+
validateForm({
|
|
678
|
+
account_type: 1,
|
|
679
|
+
})
|
|
680
|
+
).toBeUndefined();
|
|
681
|
+
});
|
|
661
682
|
});
|
|
662
683
|
describe('support "radio" field type', () => {
|
|
663
684
|
it('support "radio" field type @deprecated', () => {
|
|
@@ -1605,6 +1626,7 @@ describe('createHeadlessForm', () => {
|
|
|
1605
1626
|
type: 'text',
|
|
1606
1627
|
description: 'Enter your child’s full name',
|
|
1607
1628
|
maxLength: 255,
|
|
1629
|
+
nameKey: 'full_name',
|
|
1608
1630
|
label: 'Child Full Name',
|
|
1609
1631
|
name: 'full_name',
|
|
1610
1632
|
required: true,
|
|
@@ -1616,6 +1638,7 @@ describe('createHeadlessForm', () => {
|
|
|
1616
1638
|
required: true,
|
|
1617
1639
|
description: 'Enter your child’s date of birth',
|
|
1618
1640
|
maxLength: 255,
|
|
1641
|
+
nameKey: 'birthdate',
|
|
1619
1642
|
},
|
|
1620
1643
|
{
|
|
1621
1644
|
type: 'radio',
|
|
@@ -1634,6 +1657,7 @@ describe('createHeadlessForm', () => {
|
|
|
1634
1657
|
required: true,
|
|
1635
1658
|
description:
|
|
1636
1659
|
'We know sex is non-binary but for insurance and payroll purposes, we need to collect this information.',
|
|
1660
|
+
nameKey: 'sex',
|
|
1637
1661
|
},
|
|
1638
1662
|
]);
|
|
1639
1663
|
});
|
|
@@ -1735,63 +1759,6 @@ describe('createHeadlessForm', () => {
|
|
|
1735
1759
|
});
|
|
1736
1760
|
});
|
|
1737
1761
|
|
|
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
|
-
|
|
1795
1762
|
it('can pass custom field attributes', () => {
|
|
1796
1763
|
const result = createHeadlessForm(
|
|
1797
1764
|
{
|
package/src/tests/helpers.js
CHANGED
|
@@ -2328,58 +2328,23 @@ export const schemaWithCustomValidationsAndConditionals = {
|
|
|
2328
2328
|
],
|
|
2329
2329
|
};
|
|
2330
2330
|
|
|
2331
|
-
export const
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
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',
|
|
2331
|
+
export const schemaWithSelectInteger = {
|
|
2332
|
+
additionalProperties: false,
|
|
2333
|
+
type: 'object',
|
|
2334
|
+
properties: {
|
|
2335
|
+
account_type: {
|
|
2336
|
+
title: 'Select an account type',
|
|
2337
|
+
description: '',
|
|
2338
|
+
'x-jsf-presentation': {
|
|
2339
|
+
inputType: 'select',
|
|
2374
2340
|
},
|
|
2341
|
+
oneOf: [
|
|
2342
|
+
{ title: 'Normal User', const: 0 },
|
|
2343
|
+
{ title: 'Business', const: 1 },
|
|
2344
|
+
{ title: 'Services Provider', const: 2 },
|
|
2345
|
+
],
|
|
2346
|
+
type: 'integer',
|
|
2375
2347
|
},
|
|
2376
|
-
'x-jsf-order': ['notNested', 'nested'],
|
|
2377
|
-
required: ['notNested', 'nested'],
|
|
2378
|
-
type: 'object',
|
|
2379
2348
|
},
|
|
2380
|
-
|
|
2381
|
-
inputType: 'group-array',
|
|
2382
|
-
},
|
|
2383
|
-
title: 'Parent object',
|
|
2384
|
-
type: 'array',
|
|
2349
|
+
required: [],
|
|
2385
2350
|
};
|