@remoteoss/json-schema-form 0.11.12-dev.20250313084704 → 0.11.12-dev.20250411165200
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/dist/index.cjs +34 -23
- package/dist/index.js +34 -23
- package/dist/standalone.js +34 -23
- package/package.json +1 -1
- package/src/tests/createHeadlessForm.test.js +42 -22
- package/src/tests/helpers.js +84 -21
- package/src/tests/jsonLogic.fixtures.js +48 -0
- package/src/tests/jsonLogic.test.js +18 -0
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.12-dev.
|
|
5
|
-
Generated:
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.11.12-dev.20250411165200
|
|
5
|
+
Generated: Fri, 11 Apr 2025 16:52:23 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -613,8 +613,6 @@ var getYupSchema = ({ inputType, ...field }) => {
|
|
|
613
613
|
switch (type) {
|
|
614
614
|
case "number":
|
|
615
615
|
return yupSchemas.radioOrSelectNumber(optionValues);
|
|
616
|
-
case "integer":
|
|
617
|
-
return yupSchemas.radioOrSelectNumber(optionValues);
|
|
618
616
|
case "boolean":
|
|
619
617
|
return yupSchemas.radioOrSelectBoolean(optionValues);
|
|
620
618
|
default:
|
|
@@ -775,8 +773,7 @@ function buildYupSchema(field, config, logic) {
|
|
|
775
773
|
if (inputType === supportedTypes.FILE) {
|
|
776
774
|
validators.push(withFile);
|
|
777
775
|
}
|
|
778
|
-
|
|
779
|
-
if (jsonType === "integer" && !hasOptions) {
|
|
776
|
+
if (jsonType === "integer") {
|
|
780
777
|
validators.push(withInteger);
|
|
781
778
|
}
|
|
782
779
|
if (typeof propertyFields.minimum !== "undefined") {
|
|
@@ -1311,12 +1308,24 @@ function processNode({
|
|
|
1311
1308
|
formFields,
|
|
1312
1309
|
accRequired = /* @__PURE__ */ new Set(),
|
|
1313
1310
|
parentID = "root",
|
|
1314
|
-
logic
|
|
1311
|
+
logic,
|
|
1312
|
+
processingConditional = false
|
|
1315
1313
|
}) {
|
|
1316
1314
|
const requiredFields = new Set(accRequired);
|
|
1317
1315
|
Object.keys(node.properties ?? []).forEach((fieldName) => {
|
|
1318
1316
|
const field = getField(fieldName, formFields);
|
|
1319
1317
|
updateField(field, requiredFields, node, formValues, logic, { parentID });
|
|
1318
|
+
const nestedNode = node.properties[fieldName];
|
|
1319
|
+
const isFieldset = field.inputType === supportedTypes.FIELDSET;
|
|
1320
|
+
if (isFieldset && processingConditional) {
|
|
1321
|
+
processNode({
|
|
1322
|
+
node: nestedNode,
|
|
1323
|
+
formValues: formValues[fieldName] || {},
|
|
1324
|
+
formFields: field.fields,
|
|
1325
|
+
parentID,
|
|
1326
|
+
logic
|
|
1327
|
+
});
|
|
1328
|
+
}
|
|
1320
1329
|
});
|
|
1321
1330
|
node.required?.forEach((fieldName) => {
|
|
1322
1331
|
requiredFields.add(fieldName);
|
|
@@ -1333,7 +1342,8 @@ function processNode({
|
|
|
1333
1342
|
formFields,
|
|
1334
1343
|
accRequired: requiredFields,
|
|
1335
1344
|
parentID,
|
|
1336
|
-
logic
|
|
1345
|
+
logic,
|
|
1346
|
+
processingConditional: true
|
|
1337
1347
|
});
|
|
1338
1348
|
branchRequired.forEach((field) => requiredFields.add(field));
|
|
1339
1349
|
} else if (node.else) {
|
|
@@ -1343,7 +1353,8 @@ function processNode({
|
|
|
1343
1353
|
formFields,
|
|
1344
1354
|
accRequired: requiredFields,
|
|
1345
1355
|
parentID,
|
|
1346
|
-
logic
|
|
1356
|
+
logic,
|
|
1357
|
+
processingConditional: true
|
|
1347
1358
|
});
|
|
1348
1359
|
branchRequired.forEach((field) => requiredFields.add(field));
|
|
1349
1360
|
}
|
|
@@ -1360,20 +1371,6 @@ function processNode({
|
|
|
1360
1371
|
});
|
|
1361
1372
|
});
|
|
1362
1373
|
}
|
|
1363
|
-
if (node.allOf) {
|
|
1364
|
-
node.allOf.map(
|
|
1365
|
-
(allOfNode) => processNode({
|
|
1366
|
-
node: allOfNode,
|
|
1367
|
-
formValues,
|
|
1368
|
-
formFields,
|
|
1369
|
-
accRequired: requiredFields,
|
|
1370
|
-
parentID,
|
|
1371
|
-
logic
|
|
1372
|
-
})
|
|
1373
|
-
).forEach(({ required: allOfItemRequired }) => {
|
|
1374
|
-
allOfItemRequired.forEach(requiredFields.add, requiredFields);
|
|
1375
|
-
});
|
|
1376
|
-
}
|
|
1377
1374
|
if (node.properties) {
|
|
1378
1375
|
Object.entries(node.properties).forEach(([name, nestedNode]) => {
|
|
1379
1376
|
const inputType = getInputType(nestedNode);
|
|
@@ -1388,6 +1385,20 @@ function processNode({
|
|
|
1388
1385
|
}
|
|
1389
1386
|
});
|
|
1390
1387
|
}
|
|
1388
|
+
if (node.allOf) {
|
|
1389
|
+
node.allOf.map(
|
|
1390
|
+
(allOfNode) => processNode({
|
|
1391
|
+
node: allOfNode,
|
|
1392
|
+
formValues,
|
|
1393
|
+
formFields,
|
|
1394
|
+
accRequired: requiredFields,
|
|
1395
|
+
parentID,
|
|
1396
|
+
logic
|
|
1397
|
+
})
|
|
1398
|
+
).forEach(({ required: allOfItemRequired }) => {
|
|
1399
|
+
allOfItemRequired.forEach(requiredFields.add, requiredFields);
|
|
1400
|
+
});
|
|
1401
|
+
}
|
|
1391
1402
|
if (node["x-jsf-logic"]) {
|
|
1392
1403
|
const { required: requiredFromLogic } = processJSONLogicNode({
|
|
1393
1404
|
node: node["x-jsf-logic"],
|
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.12-dev.
|
|
5
|
-
Generated:
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.11.12-dev.20250411165200
|
|
5
|
+
Generated: Fri, 11 Apr 2025 16:52:23 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -576,8 +576,6 @@ var getYupSchema = ({ inputType, ...field }) => {
|
|
|
576
576
|
switch (type) {
|
|
577
577
|
case "number":
|
|
578
578
|
return yupSchemas.radioOrSelectNumber(optionValues);
|
|
579
|
-
case "integer":
|
|
580
|
-
return yupSchemas.radioOrSelectNumber(optionValues);
|
|
581
579
|
case "boolean":
|
|
582
580
|
return yupSchemas.radioOrSelectBoolean(optionValues);
|
|
583
581
|
default:
|
|
@@ -738,8 +736,7 @@ function buildYupSchema(field, config, logic) {
|
|
|
738
736
|
if (inputType === supportedTypes.FILE) {
|
|
739
737
|
validators.push(withFile);
|
|
740
738
|
}
|
|
741
|
-
|
|
742
|
-
if (jsonType === "integer" && !hasOptions) {
|
|
739
|
+
if (jsonType === "integer") {
|
|
743
740
|
validators.push(withInteger);
|
|
744
741
|
}
|
|
745
742
|
if (typeof propertyFields.minimum !== "undefined") {
|
|
@@ -1274,12 +1271,24 @@ function processNode({
|
|
|
1274
1271
|
formFields,
|
|
1275
1272
|
accRequired = /* @__PURE__ */ new Set(),
|
|
1276
1273
|
parentID = "root",
|
|
1277
|
-
logic
|
|
1274
|
+
logic,
|
|
1275
|
+
processingConditional = false
|
|
1278
1276
|
}) {
|
|
1279
1277
|
const requiredFields = new Set(accRequired);
|
|
1280
1278
|
Object.keys(node.properties ?? []).forEach((fieldName) => {
|
|
1281
1279
|
const field = getField(fieldName, formFields);
|
|
1282
1280
|
updateField(field, requiredFields, node, formValues, logic, { parentID });
|
|
1281
|
+
const nestedNode = node.properties[fieldName];
|
|
1282
|
+
const isFieldset = field.inputType === supportedTypes.FIELDSET;
|
|
1283
|
+
if (isFieldset && processingConditional) {
|
|
1284
|
+
processNode({
|
|
1285
|
+
node: nestedNode,
|
|
1286
|
+
formValues: formValues[fieldName] || {},
|
|
1287
|
+
formFields: field.fields,
|
|
1288
|
+
parentID,
|
|
1289
|
+
logic
|
|
1290
|
+
});
|
|
1291
|
+
}
|
|
1283
1292
|
});
|
|
1284
1293
|
node.required?.forEach((fieldName) => {
|
|
1285
1294
|
requiredFields.add(fieldName);
|
|
@@ -1296,7 +1305,8 @@ function processNode({
|
|
|
1296
1305
|
formFields,
|
|
1297
1306
|
accRequired: requiredFields,
|
|
1298
1307
|
parentID,
|
|
1299
|
-
logic
|
|
1308
|
+
logic,
|
|
1309
|
+
processingConditional: true
|
|
1300
1310
|
});
|
|
1301
1311
|
branchRequired.forEach((field) => requiredFields.add(field));
|
|
1302
1312
|
} else if (node.else) {
|
|
@@ -1306,7 +1316,8 @@ function processNode({
|
|
|
1306
1316
|
formFields,
|
|
1307
1317
|
accRequired: requiredFields,
|
|
1308
1318
|
parentID,
|
|
1309
|
-
logic
|
|
1319
|
+
logic,
|
|
1320
|
+
processingConditional: true
|
|
1310
1321
|
});
|
|
1311
1322
|
branchRequired.forEach((field) => requiredFields.add(field));
|
|
1312
1323
|
}
|
|
@@ -1323,20 +1334,6 @@ function processNode({
|
|
|
1323
1334
|
});
|
|
1324
1335
|
});
|
|
1325
1336
|
}
|
|
1326
|
-
if (node.allOf) {
|
|
1327
|
-
node.allOf.map(
|
|
1328
|
-
(allOfNode) => processNode({
|
|
1329
|
-
node: allOfNode,
|
|
1330
|
-
formValues,
|
|
1331
|
-
formFields,
|
|
1332
|
-
accRequired: requiredFields,
|
|
1333
|
-
parentID,
|
|
1334
|
-
logic
|
|
1335
|
-
})
|
|
1336
|
-
).forEach(({ required: allOfItemRequired }) => {
|
|
1337
|
-
allOfItemRequired.forEach(requiredFields.add, requiredFields);
|
|
1338
|
-
});
|
|
1339
|
-
}
|
|
1340
1337
|
if (node.properties) {
|
|
1341
1338
|
Object.entries(node.properties).forEach(([name, nestedNode]) => {
|
|
1342
1339
|
const inputType = getInputType(nestedNode);
|
|
@@ -1351,6 +1348,20 @@ function processNode({
|
|
|
1351
1348
|
}
|
|
1352
1349
|
});
|
|
1353
1350
|
}
|
|
1351
|
+
if (node.allOf) {
|
|
1352
|
+
node.allOf.map(
|
|
1353
|
+
(allOfNode) => processNode({
|
|
1354
|
+
node: allOfNode,
|
|
1355
|
+
formValues,
|
|
1356
|
+
formFields,
|
|
1357
|
+
accRequired: requiredFields,
|
|
1358
|
+
parentID,
|
|
1359
|
+
logic
|
|
1360
|
+
})
|
|
1361
|
+
).forEach(({ required: allOfItemRequired }) => {
|
|
1362
|
+
allOfItemRequired.forEach(requiredFields.add, requiredFields);
|
|
1363
|
+
});
|
|
1364
|
+
}
|
|
1354
1365
|
if (node["x-jsf-logic"]) {
|
|
1355
1366
|
const { required: requiredFromLogic } = processJSONLogicNode({
|
|
1356
1367
|
node: node["x-jsf-logic"],
|
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.12-dev.
|
|
5
|
-
Generated:
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.11.12-dev.20250411165200
|
|
5
|
+
Generated: Fri, 11 Apr 2025 16:52:23 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -12092,8 +12092,6 @@ var getYupSchema = ({ inputType, ...field }) => {
|
|
|
12092
12092
|
switch (type) {
|
|
12093
12093
|
case "number":
|
|
12094
12094
|
return yupSchemas.radioOrSelectNumber(optionValues);
|
|
12095
|
-
case "integer":
|
|
12096
|
-
return yupSchemas.radioOrSelectNumber(optionValues);
|
|
12097
12095
|
case "boolean":
|
|
12098
12096
|
return yupSchemas.radioOrSelectBoolean(optionValues);
|
|
12099
12097
|
default:
|
|
@@ -12254,8 +12252,7 @@ function buildYupSchema(field, config, logic) {
|
|
|
12254
12252
|
if (inputType === supportedTypes.FILE) {
|
|
12255
12253
|
validators.push(withFile);
|
|
12256
12254
|
}
|
|
12257
|
-
|
|
12258
|
-
if (jsonType === "integer" && !hasOptions) {
|
|
12255
|
+
if (jsonType === "integer") {
|
|
12259
12256
|
validators.push(withInteger);
|
|
12260
12257
|
}
|
|
12261
12258
|
if (typeof propertyFields.minimum !== "undefined") {
|
|
@@ -12790,12 +12787,24 @@ function processNode({
|
|
|
12790
12787
|
formFields,
|
|
12791
12788
|
accRequired = /* @__PURE__ */ new Set(),
|
|
12792
12789
|
parentID = "root",
|
|
12793
|
-
logic
|
|
12790
|
+
logic,
|
|
12791
|
+
processingConditional = false
|
|
12794
12792
|
}) {
|
|
12795
12793
|
const requiredFields = new Set(accRequired);
|
|
12796
12794
|
Object.keys(node.properties ?? []).forEach((fieldName) => {
|
|
12797
12795
|
const field = getField(fieldName, formFields);
|
|
12798
12796
|
updateField(field, requiredFields, node, formValues, logic, { parentID });
|
|
12797
|
+
const nestedNode = node.properties[fieldName];
|
|
12798
|
+
const isFieldset = field.inputType === supportedTypes.FIELDSET;
|
|
12799
|
+
if (isFieldset && processingConditional) {
|
|
12800
|
+
processNode({
|
|
12801
|
+
node: nestedNode,
|
|
12802
|
+
formValues: formValues[fieldName] || {},
|
|
12803
|
+
formFields: field.fields,
|
|
12804
|
+
parentID,
|
|
12805
|
+
logic
|
|
12806
|
+
});
|
|
12807
|
+
}
|
|
12799
12808
|
});
|
|
12800
12809
|
node.required?.forEach((fieldName) => {
|
|
12801
12810
|
requiredFields.add(fieldName);
|
|
@@ -12812,7 +12821,8 @@ function processNode({
|
|
|
12812
12821
|
formFields,
|
|
12813
12822
|
accRequired: requiredFields,
|
|
12814
12823
|
parentID,
|
|
12815
|
-
logic
|
|
12824
|
+
logic,
|
|
12825
|
+
processingConditional: true
|
|
12816
12826
|
});
|
|
12817
12827
|
branchRequired.forEach((field) => requiredFields.add(field));
|
|
12818
12828
|
} else if (node.else) {
|
|
@@ -12822,7 +12832,8 @@ function processNode({
|
|
|
12822
12832
|
formFields,
|
|
12823
12833
|
accRequired: requiredFields,
|
|
12824
12834
|
parentID,
|
|
12825
|
-
logic
|
|
12835
|
+
logic,
|
|
12836
|
+
processingConditional: true
|
|
12826
12837
|
});
|
|
12827
12838
|
branchRequired.forEach((field) => requiredFields.add(field));
|
|
12828
12839
|
}
|
|
@@ -12839,20 +12850,6 @@ function processNode({
|
|
|
12839
12850
|
});
|
|
12840
12851
|
});
|
|
12841
12852
|
}
|
|
12842
|
-
if (node.allOf) {
|
|
12843
|
-
node.allOf.map(
|
|
12844
|
-
(allOfNode) => processNode({
|
|
12845
|
-
node: allOfNode,
|
|
12846
|
-
formValues,
|
|
12847
|
-
formFields,
|
|
12848
|
-
accRequired: requiredFields,
|
|
12849
|
-
parentID,
|
|
12850
|
-
logic
|
|
12851
|
-
})
|
|
12852
|
-
).forEach(({ required: allOfItemRequired }) => {
|
|
12853
|
-
allOfItemRequired.forEach(requiredFields.add, requiredFields);
|
|
12854
|
-
});
|
|
12855
|
-
}
|
|
12856
12853
|
if (node.properties) {
|
|
12857
12854
|
Object.entries(node.properties).forEach(([name, nestedNode]) => {
|
|
12858
12855
|
const inputType = getInputType(nestedNode);
|
|
@@ -12867,6 +12864,20 @@ function processNode({
|
|
|
12867
12864
|
}
|
|
12868
12865
|
});
|
|
12869
12866
|
}
|
|
12867
|
+
if (node.allOf) {
|
|
12868
|
+
node.allOf.map(
|
|
12869
|
+
(allOfNode) => processNode({
|
|
12870
|
+
node: allOfNode,
|
|
12871
|
+
formValues,
|
|
12872
|
+
formFields,
|
|
12873
|
+
accRequired: requiredFields,
|
|
12874
|
+
parentID,
|
|
12875
|
+
logic
|
|
12876
|
+
})
|
|
12877
|
+
).forEach(({ required: allOfItemRequired }) => {
|
|
12878
|
+
allOfItemRequired.forEach(requiredFields.add, requiredFields);
|
|
12879
|
+
});
|
|
12880
|
+
}
|
|
12870
12881
|
if (node["x-jsf-logic"]) {
|
|
12871
12882
|
const { required: requiredFromLogic } = processJSONLogicNode({
|
|
12872
12883
|
node: node["x-jsf-logic"],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remoteoss/json-schema-form",
|
|
3
|
-
"version": "0.11.12-dev.
|
|
3
|
+
"version": "0.11.12-dev.20250411165200",
|
|
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",
|
|
@@ -63,7 +63,7 @@ import {
|
|
|
63
63
|
schemaForErrorMessageSpecificity,
|
|
64
64
|
jsfConfigForErrorMessageSpecificity,
|
|
65
65
|
schemaInputTypeFile,
|
|
66
|
-
|
|
66
|
+
schemaWithRootFieldsetsConditionals,
|
|
67
67
|
} from './helpers';
|
|
68
68
|
import { mockConsole, restoreConsoleAndEnsureItWasNotCalled } from './testUtils';
|
|
69
69
|
import { createHeadlessForm } from '@/createHeadlessForm';
|
|
@@ -658,27 +658,6 @@ 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
|
-
});
|
|
682
661
|
});
|
|
683
662
|
describe('support "radio" field type', () => {
|
|
684
663
|
it('support "radio" field type @deprecated', () => {
|
|
@@ -2184,6 +2163,47 @@ describe('createHeadlessForm', () => {
|
|
|
2184
2163
|
).toBeUndefined();
|
|
2185
2164
|
});
|
|
2186
2165
|
});
|
|
2166
|
+
|
|
2167
|
+
describe('supports root fieldsets conditionals', () => {
|
|
2168
|
+
it('Given a basic retirement, the perks.has_pension is hidden', async () => {
|
|
2169
|
+
const { fields, handleValidation } = createHeadlessForm(
|
|
2170
|
+
schemaWithRootFieldsetsConditionals,
|
|
2171
|
+
{}
|
|
2172
|
+
);
|
|
2173
|
+
const validateForm = (vals) => friendlyError(handleValidation(vals));
|
|
2174
|
+
|
|
2175
|
+
expect(validateForm({})).toEqual({
|
|
2176
|
+
perks: {
|
|
2177
|
+
retirement: 'Required field',
|
|
2178
|
+
},
|
|
2179
|
+
});
|
|
2180
|
+
|
|
2181
|
+
// has_pension is not visible
|
|
2182
|
+
expect(getField(fields, 'perks', 'has_pension').isVisible).toBe(false);
|
|
2183
|
+
|
|
2184
|
+
expect(
|
|
2185
|
+
validateForm({
|
|
2186
|
+
perks: { retirement: 'plus' },
|
|
2187
|
+
})
|
|
2188
|
+
).toEqual({
|
|
2189
|
+
perks: {
|
|
2190
|
+
has_pension: 'Required field',
|
|
2191
|
+
},
|
|
2192
|
+
});
|
|
2193
|
+
|
|
2194
|
+
// field becomes visible
|
|
2195
|
+
expect(getField(fields, 'perks', 'has_pension').isVisible).toBe(true);
|
|
2196
|
+
|
|
2197
|
+
expect(
|
|
2198
|
+
validateForm({
|
|
2199
|
+
perks: { retirement: 'basic' },
|
|
2200
|
+
})
|
|
2201
|
+
).toBeUndefined();
|
|
2202
|
+
|
|
2203
|
+
// field becomes invisible
|
|
2204
|
+
expect(getField(fields, 'perks', 'has_pension').isVisible).toBe(false);
|
|
2205
|
+
});
|
|
2206
|
+
});
|
|
2187
2207
|
});
|
|
2188
2208
|
|
|
2189
2209
|
it('support "email" field type', () => {
|
package/src/tests/helpers.js
CHANGED
|
@@ -1973,6 +1973,90 @@ export const schemaWithConditionalToFieldset = {
|
|
|
1973
1973
|
required: ['perks', 'work_hours_per_week'],
|
|
1974
1974
|
};
|
|
1975
1975
|
|
|
1976
|
+
export const schemaWithRootFieldsetsConditionals = {
|
|
1977
|
+
additionalProperties: false,
|
|
1978
|
+
type: 'object',
|
|
1979
|
+
properties: {
|
|
1980
|
+
perks: {
|
|
1981
|
+
additionalProperties: false,
|
|
1982
|
+
properties: {
|
|
1983
|
+
retirement: {
|
|
1984
|
+
oneOf: [
|
|
1985
|
+
{
|
|
1986
|
+
const: 'basic',
|
|
1987
|
+
title: 'Basic',
|
|
1988
|
+
},
|
|
1989
|
+
{
|
|
1990
|
+
const: 'plus',
|
|
1991
|
+
title: 'Plus',
|
|
1992
|
+
},
|
|
1993
|
+
],
|
|
1994
|
+
title: 'Retirement',
|
|
1995
|
+
type: 'string',
|
|
1996
|
+
'x-jsf-presentation': {
|
|
1997
|
+
inputType: 'radio',
|
|
1998
|
+
},
|
|
1999
|
+
},
|
|
2000
|
+
has_pension: {
|
|
2001
|
+
oneOf: [
|
|
2002
|
+
{
|
|
2003
|
+
const: 'yes',
|
|
2004
|
+
title: 'Yes',
|
|
2005
|
+
},
|
|
2006
|
+
{
|
|
2007
|
+
const: 'no',
|
|
2008
|
+
title: 'No',
|
|
2009
|
+
},
|
|
2010
|
+
],
|
|
2011
|
+
title: 'Has pension',
|
|
2012
|
+
type: 'string',
|
|
2013
|
+
'x-jsf-presentation': {
|
|
2014
|
+
inputType: 'radio',
|
|
2015
|
+
},
|
|
2016
|
+
},
|
|
2017
|
+
},
|
|
2018
|
+
required: ['retirement'],
|
|
2019
|
+
title: 'Perks',
|
|
2020
|
+
type: 'object',
|
|
2021
|
+
'x-jsf-presentation': {
|
|
2022
|
+
inputType: 'fieldset',
|
|
2023
|
+
},
|
|
2024
|
+
},
|
|
2025
|
+
},
|
|
2026
|
+
required: ['perks'],
|
|
2027
|
+
allOf: [
|
|
2028
|
+
{
|
|
2029
|
+
if: {
|
|
2030
|
+
properties: {
|
|
2031
|
+
perks: {
|
|
2032
|
+
properties: {
|
|
2033
|
+
retirement: {
|
|
2034
|
+
const: 'basic',
|
|
2035
|
+
},
|
|
2036
|
+
},
|
|
2037
|
+
},
|
|
2038
|
+
},
|
|
2039
|
+
},
|
|
2040
|
+
then: {
|
|
2041
|
+
properties: {
|
|
2042
|
+
perks: {
|
|
2043
|
+
properties: {
|
|
2044
|
+
has_pension: false,
|
|
2045
|
+
},
|
|
2046
|
+
},
|
|
2047
|
+
},
|
|
2048
|
+
},
|
|
2049
|
+
else: {
|
|
2050
|
+
properties: {
|
|
2051
|
+
perks: {
|
|
2052
|
+
required: ['has_pension'],
|
|
2053
|
+
},
|
|
2054
|
+
},
|
|
2055
|
+
},
|
|
2056
|
+
},
|
|
2057
|
+
],
|
|
2058
|
+
};
|
|
2059
|
+
|
|
1976
2060
|
export const schemaWorkSchedule = {
|
|
1977
2061
|
type: 'object',
|
|
1978
2062
|
properties: {
|
|
@@ -2327,24 +2411,3 @@ export const schemaWithCustomValidationsAndConditionals = {
|
|
|
2327
2411
|
},
|
|
2328
2412
|
],
|
|
2329
2413
|
};
|
|
2330
|
-
|
|
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',
|
|
2340
|
-
},
|
|
2341
|
-
oneOf: [
|
|
2342
|
-
{ title: 'Normal User', const: 0 },
|
|
2343
|
-
{ title: 'Business', const: 1 },
|
|
2344
|
-
{ title: 'Services Provider', const: 2 },
|
|
2345
|
-
],
|
|
2346
|
-
type: 'integer',
|
|
2347
|
-
},
|
|
2348
|
-
},
|
|
2349
|
-
required: [],
|
|
2350
|
-
};
|
|
@@ -984,3 +984,51 @@ export const schemaWithTwoValidationsWhereOneOfThemIsAppliedConditionally = {
|
|
|
984
984
|
},
|
|
985
985
|
],
|
|
986
986
|
};
|
|
987
|
+
|
|
988
|
+
export const schemaWithReduceAccumulator = {
|
|
989
|
+
properties: {
|
|
990
|
+
work_days: {
|
|
991
|
+
items: {
|
|
992
|
+
anyOf: [
|
|
993
|
+
{ const: 'monday', title: 'Monday' },
|
|
994
|
+
{ const: 'tuesday', title: 'Tuesday' },
|
|
995
|
+
{ const: 'wednesday', title: 'Wednesday' },
|
|
996
|
+
{ const: 'thursday', title: 'Thursday' },
|
|
997
|
+
{ const: 'friday', title: 'Friday' },
|
|
998
|
+
{ const: 'saturday', title: 'Saturday' },
|
|
999
|
+
{ const: 'sunday', title: 'Sunday' },
|
|
1000
|
+
],
|
|
1001
|
+
},
|
|
1002
|
+
type: 'array',
|
|
1003
|
+
uniqueItems: true,
|
|
1004
|
+
'x-jsf-presentation': {
|
|
1005
|
+
inputType: 'select',
|
|
1006
|
+
},
|
|
1007
|
+
},
|
|
1008
|
+
working_hours_per_day: {
|
|
1009
|
+
type: 'number',
|
|
1010
|
+
},
|
|
1011
|
+
working_hours_per_week: {
|
|
1012
|
+
type: 'number',
|
|
1013
|
+
'x-jsf-logic-computedAttrs': {
|
|
1014
|
+
const: 'computed_work_hours_per_week',
|
|
1015
|
+
defaultValue: 'computed_work_hours_per_week',
|
|
1016
|
+
title: '{{computed_work_hours_per_week}} hours per week',
|
|
1017
|
+
},
|
|
1018
|
+
},
|
|
1019
|
+
},
|
|
1020
|
+
'x-jsf-logic': {
|
|
1021
|
+
computedValues: {
|
|
1022
|
+
computed_work_hours_per_week: {
|
|
1023
|
+
rule: {
|
|
1024
|
+
'*': [
|
|
1025
|
+
{ var: 'working_hours_per_day' },
|
|
1026
|
+
{
|
|
1027
|
+
reduce: [{ var: 'work_days' }, { '+': [{ var: ['accumulator', 0] }, 1] }, 0],
|
|
1028
|
+
},
|
|
1029
|
+
],
|
|
1030
|
+
},
|
|
1031
|
+
},
|
|
1032
|
+
},
|
|
1033
|
+
},
|
|
1034
|
+
};
|
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
schemaWithUnknownVariableInValidations,
|
|
35
35
|
schemaWithValidationThatDoesNotExistOnProperty,
|
|
36
36
|
badSchemaThatWillNotSetAForcedValue,
|
|
37
|
+
schemaWithReduceAccumulator,
|
|
37
38
|
} from './jsonLogic.fixtures';
|
|
38
39
|
import { mockConsole, restoreConsoleAndEnsureItWasNotCalled } from './testUtils';
|
|
39
40
|
import { createHeadlessForm } from '@/createHeadlessForm';
|
|
@@ -243,6 +244,23 @@ describe('jsonLogic: cross-values validations', () => {
|
|
|
243
244
|
});
|
|
244
245
|
});
|
|
245
246
|
|
|
247
|
+
// TODO: Implement this test.
|
|
248
|
+
describe.skip('Reduce', () => {
|
|
249
|
+
it('reduce: working_hours_per_day * work_days', () => {
|
|
250
|
+
const { fields, handleValidation } = createHeadlessForm(schemaWithReduceAccumulator, {
|
|
251
|
+
strictInputType: false,
|
|
252
|
+
});
|
|
253
|
+
handleValidation({
|
|
254
|
+
work_days: ['monday', 'tuesday'],
|
|
255
|
+
working_hours_per_day: 8,
|
|
256
|
+
});
|
|
257
|
+
const field = fields.find((i) => i.name === 'working_hours_per_week');
|
|
258
|
+
expect(field.const).toEqual(16);
|
|
259
|
+
expect(field.default).toEqual(16);
|
|
260
|
+
expect(field.label).toEqual('16 hours per week');
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
|
|
246
264
|
describe('Logical: ||, &&', () => {
|
|
247
265
|
it('AND: field_a > field_b && field_a > field_c (implicit with multiple rules in a single field)', () => {
|
|
248
266
|
const schema = createSchemaWithThreePropertiesWithRuleOnFieldA({
|