@remoteoss/json-schema-form 0.12.1-dev.20251008013953 → 0.12.2-beta.0
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 +12 -0
- package/dist/index.cjs +34 -28
- package/dist/index.js +34 -28
- package/dist/standalone.js +34 -28
- package/package.json +2 -2
- package/src/tests/createHeadlessForm.test.js +186 -0
- package/src/tests/helpers.js +383 -1
- /package/src/tests/{utils.test.jsx → utils.test.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
#### 0.12.2-beta.0 (2025-10-23)
|
|
2
|
+
|
|
3
|
+
##### New Features
|
|
4
|
+
|
|
5
|
+
* **v0:** Support nested fieldset conditionals ([#156](https://github.com/remoteoss/json-schema-form/pull/156)) ([877e82e1](https://github.com/remoteoss/json-schema-form/commit/877e82e148d1ff6964ba634108f8ca821c040565))
|
|
6
|
+
|
|
7
|
+
#### 0.12.1-beta.0 (2025-10-09)
|
|
8
|
+
|
|
9
|
+
##### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **checkbox:** Support optional boolean type for v0 ([#236](https://github.com/remoteoss/json-schema-form/pull/236)) ([76e8927f](https://github.com/remoteoss/json-schema-form/commit/76e8927fc2f4615620fe34eef303b2f9c8c81e6e))
|
|
12
|
+
|
|
1
13
|
#### 0.12.0-beta.0 (2025-06-25)
|
|
2
14
|
|
|
3
15
|
##### New Features
|
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.12.
|
|
5
|
-
Generated:
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.12.2-beta.0
|
|
5
|
+
Generated: Thu, 23 Oct 2025 14:03:06 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -737,9 +737,7 @@ function buildYupSchema(field, config, logic) {
|
|
|
737
737
|
const fieldSetShape = {};
|
|
738
738
|
innerFields.forEach((fieldSetfield) => {
|
|
739
739
|
if (fieldSetfield.fields) {
|
|
740
|
-
fieldSetShape[fieldSetfield.name] = (0, import_yup.object)().shape(
|
|
741
|
-
buildFieldSetSchema(fieldSetfield.fields)
|
|
742
|
-
);
|
|
740
|
+
fieldSetShape[fieldSetfield.name] = (0, import_yup.object)().shape(buildFieldSetSchema(fieldSetfield.fields)).nullable();
|
|
743
741
|
} else {
|
|
744
742
|
fieldSetShape[fieldSetfield.name] = buildYupSchema(
|
|
745
743
|
{
|
|
@@ -1308,7 +1306,8 @@ function updateField(field, requiredFields, node, formValues, logic, config) {
|
|
|
1308
1306
|
const { rootFieldAttrs, newAttributes } = field.calculateConditionalProperties({
|
|
1309
1307
|
isRequired: fieldIsRequired,
|
|
1310
1308
|
conditionBranch: node,
|
|
1311
|
-
formValues
|
|
1309
|
+
formValues,
|
|
1310
|
+
currentField: field
|
|
1312
1311
|
});
|
|
1313
1312
|
updateAttributes(newAttributes);
|
|
1314
1313
|
removeConditionalStaleAttributes(field, newAttributes, rootFieldAttrs);
|
|
@@ -1331,9 +1330,19 @@ function processNode({
|
|
|
1331
1330
|
logic
|
|
1332
1331
|
}) {
|
|
1333
1332
|
const requiredFields = new Set(accRequired);
|
|
1334
|
-
Object.
|
|
1333
|
+
Object.entries(node.properties ?? []).forEach(([fieldName, nestedNode]) => {
|
|
1335
1334
|
const field = getField(fieldName, formFields);
|
|
1336
1335
|
updateField(field, requiredFields, node, formValues, logic, { parentID });
|
|
1336
|
+
const isFieldset = field?.inputType === supportedTypes.FIELDSET;
|
|
1337
|
+
if (isFieldset) {
|
|
1338
|
+
processNode({
|
|
1339
|
+
node: nestedNode,
|
|
1340
|
+
formValues: formValues[fieldName] || {},
|
|
1341
|
+
formFields: field.fields,
|
|
1342
|
+
parentID,
|
|
1343
|
+
logic
|
|
1344
|
+
});
|
|
1345
|
+
}
|
|
1337
1346
|
});
|
|
1338
1347
|
node.required?.forEach((fieldName) => {
|
|
1339
1348
|
requiredFields.add(fieldName);
|
|
@@ -1391,20 +1400,6 @@ function processNode({
|
|
|
1391
1400
|
allOfItemRequired.forEach(requiredFields.add, requiredFields);
|
|
1392
1401
|
});
|
|
1393
1402
|
}
|
|
1394
|
-
if (node.properties) {
|
|
1395
|
-
Object.entries(node.properties).forEach(([name, nestedNode]) => {
|
|
1396
|
-
const inputType = getInputType(nestedNode);
|
|
1397
|
-
if (inputType === supportedTypes.FIELDSET) {
|
|
1398
|
-
processNode({
|
|
1399
|
-
node: nestedNode,
|
|
1400
|
-
formValues: formValues[name] || {},
|
|
1401
|
-
formFields: getField(name, formFields).fields,
|
|
1402
|
-
parentID: name,
|
|
1403
|
-
logic
|
|
1404
|
-
});
|
|
1405
|
-
}
|
|
1406
|
-
});
|
|
1407
|
-
}
|
|
1408
1403
|
if (node["x-jsf-logic"]) {
|
|
1409
1404
|
const { required: requiredFromLogic } = processJSONLogicNode({
|
|
1410
1405
|
node: node["x-jsf-logic"],
|
|
@@ -1596,35 +1591,42 @@ function isFieldRequired(node, field) {
|
|
|
1596
1591
|
node?.required?.includes(field.name)
|
|
1597
1592
|
);
|
|
1598
1593
|
}
|
|
1599
|
-
function rebuildFieldset(fields, property) {
|
|
1594
|
+
function rebuildFieldset(fields, currentFields, property) {
|
|
1600
1595
|
if (property?.properties) {
|
|
1601
|
-
return fields.map((field) => {
|
|
1596
|
+
return fields.map((field, index) => {
|
|
1602
1597
|
const propertyConditionals = property.properties[field.name];
|
|
1598
|
+
const isVisible = currentFields[index].isVisible;
|
|
1603
1599
|
if (!propertyConditionals) {
|
|
1604
|
-
return
|
|
1600
|
+
return {
|
|
1601
|
+
...field,
|
|
1602
|
+
isVisible
|
|
1603
|
+
};
|
|
1605
1604
|
}
|
|
1606
1605
|
const newFieldParams = extractParametersFromNode(propertyConditionals);
|
|
1607
1606
|
if (field.fields) {
|
|
1608
1607
|
return {
|
|
1609
1608
|
...field,
|
|
1610
1609
|
...newFieldParams,
|
|
1611
|
-
|
|
1610
|
+
isVisible,
|
|
1611
|
+
fields: rebuildFieldset(field.fields, currentFields[index].fields, propertyConditionals)
|
|
1612
1612
|
};
|
|
1613
1613
|
}
|
|
1614
1614
|
return {
|
|
1615
1615
|
...field,
|
|
1616
1616
|
...newFieldParams,
|
|
1617
|
+
isVisible,
|
|
1617
1618
|
required: isFieldRequired(property, field)
|
|
1618
1619
|
};
|
|
1619
1620
|
});
|
|
1620
1621
|
}
|
|
1621
|
-
return fields.map((field) => ({
|
|
1622
|
+
return fields.map((field, index) => ({
|
|
1622
1623
|
...field,
|
|
1624
|
+
isVisible: currentFields[index].isVisible,
|
|
1623
1625
|
required: isFieldRequired(property, field)
|
|
1624
1626
|
}));
|
|
1625
1627
|
}
|
|
1626
1628
|
function calculateConditionalProperties({ fieldParams, customProperties, logic, config }) {
|
|
1627
|
-
return ({ isRequired, conditionBranch, formValues }) => {
|
|
1629
|
+
return ({ isRequired, conditionBranch, formValues, currentField }) => {
|
|
1628
1630
|
const conditionalProperty = conditionBranch?.properties?.[fieldParams.name];
|
|
1629
1631
|
if (conditionalProperty) {
|
|
1630
1632
|
const presentation = pickXKey(conditionalProperty, "presentation") ?? {};
|
|
@@ -1635,7 +1637,11 @@ function calculateConditionalProperties({ fieldParams, customProperties, logic,
|
|
|
1635
1637
|
});
|
|
1636
1638
|
let fieldSetFields;
|
|
1637
1639
|
if (fieldParams.inputType === supportedTypes.FIELDSET) {
|
|
1638
|
-
fieldSetFields = rebuildFieldset(
|
|
1640
|
+
fieldSetFields = rebuildFieldset(
|
|
1641
|
+
fieldParams.fields,
|
|
1642
|
+
currentField.fields,
|
|
1643
|
+
conditionalProperty
|
|
1644
|
+
);
|
|
1639
1645
|
newFieldParams.fields = fieldSetFields;
|
|
1640
1646
|
}
|
|
1641
1647
|
const { computedAttributes, ...restNewFieldParams } = newFieldParams;
|
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.12.
|
|
5
|
-
Generated:
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.12.2-beta.0
|
|
5
|
+
Generated: Thu, 23 Oct 2025 14:03:06 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -699,9 +699,7 @@ function buildYupSchema(field, config, logic) {
|
|
|
699
699
|
const fieldSetShape = {};
|
|
700
700
|
innerFields.forEach((fieldSetfield) => {
|
|
701
701
|
if (fieldSetfield.fields) {
|
|
702
|
-
fieldSetShape[fieldSetfield.name] = object().shape(
|
|
703
|
-
buildFieldSetSchema(fieldSetfield.fields)
|
|
704
|
-
);
|
|
702
|
+
fieldSetShape[fieldSetfield.name] = object().shape(buildFieldSetSchema(fieldSetfield.fields)).nullable();
|
|
705
703
|
} else {
|
|
706
704
|
fieldSetShape[fieldSetfield.name] = buildYupSchema(
|
|
707
705
|
{
|
|
@@ -1270,7 +1268,8 @@ function updateField(field, requiredFields, node, formValues, logic, config) {
|
|
|
1270
1268
|
const { rootFieldAttrs, newAttributes } = field.calculateConditionalProperties({
|
|
1271
1269
|
isRequired: fieldIsRequired,
|
|
1272
1270
|
conditionBranch: node,
|
|
1273
|
-
formValues
|
|
1271
|
+
formValues,
|
|
1272
|
+
currentField: field
|
|
1274
1273
|
});
|
|
1275
1274
|
updateAttributes(newAttributes);
|
|
1276
1275
|
removeConditionalStaleAttributes(field, newAttributes, rootFieldAttrs);
|
|
@@ -1293,9 +1292,19 @@ function processNode({
|
|
|
1293
1292
|
logic
|
|
1294
1293
|
}) {
|
|
1295
1294
|
const requiredFields = new Set(accRequired);
|
|
1296
|
-
Object.
|
|
1295
|
+
Object.entries(node.properties ?? []).forEach(([fieldName, nestedNode]) => {
|
|
1297
1296
|
const field = getField(fieldName, formFields);
|
|
1298
1297
|
updateField(field, requiredFields, node, formValues, logic, { parentID });
|
|
1298
|
+
const isFieldset = field?.inputType === supportedTypes.FIELDSET;
|
|
1299
|
+
if (isFieldset) {
|
|
1300
|
+
processNode({
|
|
1301
|
+
node: nestedNode,
|
|
1302
|
+
formValues: formValues[fieldName] || {},
|
|
1303
|
+
formFields: field.fields,
|
|
1304
|
+
parentID,
|
|
1305
|
+
logic
|
|
1306
|
+
});
|
|
1307
|
+
}
|
|
1299
1308
|
});
|
|
1300
1309
|
node.required?.forEach((fieldName) => {
|
|
1301
1310
|
requiredFields.add(fieldName);
|
|
@@ -1353,20 +1362,6 @@ function processNode({
|
|
|
1353
1362
|
allOfItemRequired.forEach(requiredFields.add, requiredFields);
|
|
1354
1363
|
});
|
|
1355
1364
|
}
|
|
1356
|
-
if (node.properties) {
|
|
1357
|
-
Object.entries(node.properties).forEach(([name, nestedNode]) => {
|
|
1358
|
-
const inputType = getInputType(nestedNode);
|
|
1359
|
-
if (inputType === supportedTypes.FIELDSET) {
|
|
1360
|
-
processNode({
|
|
1361
|
-
node: nestedNode,
|
|
1362
|
-
formValues: formValues[name] || {},
|
|
1363
|
-
formFields: getField(name, formFields).fields,
|
|
1364
|
-
parentID: name,
|
|
1365
|
-
logic
|
|
1366
|
-
});
|
|
1367
|
-
}
|
|
1368
|
-
});
|
|
1369
|
-
}
|
|
1370
1365
|
if (node["x-jsf-logic"]) {
|
|
1371
1366
|
const { required: requiredFromLogic } = processJSONLogicNode({
|
|
1372
1367
|
node: node["x-jsf-logic"],
|
|
@@ -1558,35 +1553,42 @@ function isFieldRequired(node, field) {
|
|
|
1558
1553
|
node?.required?.includes(field.name)
|
|
1559
1554
|
);
|
|
1560
1555
|
}
|
|
1561
|
-
function rebuildFieldset(fields, property) {
|
|
1556
|
+
function rebuildFieldset(fields, currentFields, property) {
|
|
1562
1557
|
if (property?.properties) {
|
|
1563
|
-
return fields.map((field) => {
|
|
1558
|
+
return fields.map((field, index) => {
|
|
1564
1559
|
const propertyConditionals = property.properties[field.name];
|
|
1560
|
+
const isVisible = currentFields[index].isVisible;
|
|
1565
1561
|
if (!propertyConditionals) {
|
|
1566
|
-
return
|
|
1562
|
+
return {
|
|
1563
|
+
...field,
|
|
1564
|
+
isVisible
|
|
1565
|
+
};
|
|
1567
1566
|
}
|
|
1568
1567
|
const newFieldParams = extractParametersFromNode(propertyConditionals);
|
|
1569
1568
|
if (field.fields) {
|
|
1570
1569
|
return {
|
|
1571
1570
|
...field,
|
|
1572
1571
|
...newFieldParams,
|
|
1573
|
-
|
|
1572
|
+
isVisible,
|
|
1573
|
+
fields: rebuildFieldset(field.fields, currentFields[index].fields, propertyConditionals)
|
|
1574
1574
|
};
|
|
1575
1575
|
}
|
|
1576
1576
|
return {
|
|
1577
1577
|
...field,
|
|
1578
1578
|
...newFieldParams,
|
|
1579
|
+
isVisible,
|
|
1579
1580
|
required: isFieldRequired(property, field)
|
|
1580
1581
|
};
|
|
1581
1582
|
});
|
|
1582
1583
|
}
|
|
1583
|
-
return fields.map((field) => ({
|
|
1584
|
+
return fields.map((field, index) => ({
|
|
1584
1585
|
...field,
|
|
1586
|
+
isVisible: currentFields[index].isVisible,
|
|
1585
1587
|
required: isFieldRequired(property, field)
|
|
1586
1588
|
}));
|
|
1587
1589
|
}
|
|
1588
1590
|
function calculateConditionalProperties({ fieldParams, customProperties, logic, config }) {
|
|
1589
|
-
return ({ isRequired, conditionBranch, formValues }) => {
|
|
1591
|
+
return ({ isRequired, conditionBranch, formValues, currentField }) => {
|
|
1590
1592
|
const conditionalProperty = conditionBranch?.properties?.[fieldParams.name];
|
|
1591
1593
|
if (conditionalProperty) {
|
|
1592
1594
|
const presentation = pickXKey(conditionalProperty, "presentation") ?? {};
|
|
@@ -1597,7 +1599,11 @@ function calculateConditionalProperties({ fieldParams, customProperties, logic,
|
|
|
1597
1599
|
});
|
|
1598
1600
|
let fieldSetFields;
|
|
1599
1601
|
if (fieldParams.inputType === supportedTypes.FIELDSET) {
|
|
1600
|
-
fieldSetFields = rebuildFieldset(
|
|
1602
|
+
fieldSetFields = rebuildFieldset(
|
|
1603
|
+
fieldParams.fields,
|
|
1604
|
+
currentField.fields,
|
|
1605
|
+
conditionalProperty
|
|
1606
|
+
);
|
|
1601
1607
|
newFieldParams.fields = fieldSetFields;
|
|
1602
1608
|
}
|
|
1603
1609
|
const { computedAttributes, ...restNewFieldParams } = newFieldParams;
|
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.12.
|
|
5
|
-
Generated:
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.12.2-beta.0
|
|
5
|
+
Generated: Thu, 23 Oct 2025 14:03:06 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -12215,9 +12215,7 @@ function buildYupSchema(field, config, logic) {
|
|
|
12215
12215
|
const fieldSetShape = {};
|
|
12216
12216
|
innerFields.forEach((fieldSetfield) => {
|
|
12217
12217
|
if (fieldSetfield.fields) {
|
|
12218
|
-
fieldSetShape[fieldSetfield.name] = ObjectSchema().shape(
|
|
12219
|
-
buildFieldSetSchema(fieldSetfield.fields)
|
|
12220
|
-
);
|
|
12218
|
+
fieldSetShape[fieldSetfield.name] = ObjectSchema().shape(buildFieldSetSchema(fieldSetfield.fields)).nullable();
|
|
12221
12219
|
} else {
|
|
12222
12220
|
fieldSetShape[fieldSetfield.name] = buildYupSchema(
|
|
12223
12221
|
{
|
|
@@ -12786,7 +12784,8 @@ function updateField(field, requiredFields, node, formValues, logic, config) {
|
|
|
12786
12784
|
const { rootFieldAttrs, newAttributes } = field.calculateConditionalProperties({
|
|
12787
12785
|
isRequired: fieldIsRequired,
|
|
12788
12786
|
conditionBranch: node,
|
|
12789
|
-
formValues
|
|
12787
|
+
formValues,
|
|
12788
|
+
currentField: field
|
|
12790
12789
|
});
|
|
12791
12790
|
updateAttributes(newAttributes);
|
|
12792
12791
|
removeConditionalStaleAttributes(field, newAttributes, rootFieldAttrs);
|
|
@@ -12809,9 +12808,19 @@ function processNode({
|
|
|
12809
12808
|
logic
|
|
12810
12809
|
}) {
|
|
12811
12810
|
const requiredFields = new Set(accRequired);
|
|
12812
|
-
Object.
|
|
12811
|
+
Object.entries(node.properties ?? []).forEach(([fieldName, nestedNode]) => {
|
|
12813
12812
|
const field = getField(fieldName, formFields);
|
|
12814
12813
|
updateField(field, requiredFields, node, formValues, logic, { parentID });
|
|
12814
|
+
const isFieldset = field?.inputType === supportedTypes.FIELDSET;
|
|
12815
|
+
if (isFieldset) {
|
|
12816
|
+
processNode({
|
|
12817
|
+
node: nestedNode,
|
|
12818
|
+
formValues: formValues[fieldName] || {},
|
|
12819
|
+
formFields: field.fields,
|
|
12820
|
+
parentID,
|
|
12821
|
+
logic
|
|
12822
|
+
});
|
|
12823
|
+
}
|
|
12815
12824
|
});
|
|
12816
12825
|
node.required?.forEach((fieldName) => {
|
|
12817
12826
|
requiredFields.add(fieldName);
|
|
@@ -12869,20 +12878,6 @@ function processNode({
|
|
|
12869
12878
|
allOfItemRequired.forEach(requiredFields.add, requiredFields);
|
|
12870
12879
|
});
|
|
12871
12880
|
}
|
|
12872
|
-
if (node.properties) {
|
|
12873
|
-
Object.entries(node.properties).forEach(([name, nestedNode]) => {
|
|
12874
|
-
const inputType = getInputType(nestedNode);
|
|
12875
|
-
if (inputType === supportedTypes.FIELDSET) {
|
|
12876
|
-
processNode({
|
|
12877
|
-
node: nestedNode,
|
|
12878
|
-
formValues: formValues[name] || {},
|
|
12879
|
-
formFields: getField(name, formFields).fields,
|
|
12880
|
-
parentID: name,
|
|
12881
|
-
logic
|
|
12882
|
-
});
|
|
12883
|
-
}
|
|
12884
|
-
});
|
|
12885
|
-
}
|
|
12886
12881
|
if (node["x-jsf-logic"]) {
|
|
12887
12882
|
const { required: requiredFromLogic } = processJSONLogicNode({
|
|
12888
12883
|
node: node["x-jsf-logic"],
|
|
@@ -13074,35 +13069,42 @@ function isFieldRequired(node, field) {
|
|
|
13074
13069
|
node?.required?.includes(field.name)
|
|
13075
13070
|
);
|
|
13076
13071
|
}
|
|
13077
|
-
function rebuildFieldset(fields, property2) {
|
|
13072
|
+
function rebuildFieldset(fields, currentFields, property2) {
|
|
13078
13073
|
if (property2?.properties) {
|
|
13079
|
-
return fields.map((field) => {
|
|
13074
|
+
return fields.map((field, index) => {
|
|
13080
13075
|
const propertyConditionals = property2.properties[field.name];
|
|
13076
|
+
const isVisible = currentFields[index].isVisible;
|
|
13081
13077
|
if (!propertyConditionals) {
|
|
13082
|
-
return
|
|
13078
|
+
return {
|
|
13079
|
+
...field,
|
|
13080
|
+
isVisible
|
|
13081
|
+
};
|
|
13083
13082
|
}
|
|
13084
13083
|
const newFieldParams = extractParametersFromNode(propertyConditionals);
|
|
13085
13084
|
if (field.fields) {
|
|
13086
13085
|
return {
|
|
13087
13086
|
...field,
|
|
13088
13087
|
...newFieldParams,
|
|
13089
|
-
|
|
13088
|
+
isVisible,
|
|
13089
|
+
fields: rebuildFieldset(field.fields, currentFields[index].fields, propertyConditionals)
|
|
13090
13090
|
};
|
|
13091
13091
|
}
|
|
13092
13092
|
return {
|
|
13093
13093
|
...field,
|
|
13094
13094
|
...newFieldParams,
|
|
13095
|
+
isVisible,
|
|
13095
13096
|
required: isFieldRequired(property2, field)
|
|
13096
13097
|
};
|
|
13097
13098
|
});
|
|
13098
13099
|
}
|
|
13099
|
-
return fields.map((field) => ({
|
|
13100
|
+
return fields.map((field, index) => ({
|
|
13100
13101
|
...field,
|
|
13102
|
+
isVisible: currentFields[index].isVisible,
|
|
13101
13103
|
required: isFieldRequired(property2, field)
|
|
13102
13104
|
}));
|
|
13103
13105
|
}
|
|
13104
13106
|
function calculateConditionalProperties({ fieldParams, customProperties, logic, config }) {
|
|
13105
|
-
return ({ isRequired, conditionBranch, formValues }) => {
|
|
13107
|
+
return ({ isRequired, conditionBranch, formValues, currentField }) => {
|
|
13106
13108
|
const conditionalProperty = conditionBranch?.properties?.[fieldParams.name];
|
|
13107
13109
|
if (conditionalProperty) {
|
|
13108
13110
|
const presentation = pickXKey(conditionalProperty, "presentation") ?? {};
|
|
@@ -13113,7 +13115,11 @@ function calculateConditionalProperties({ fieldParams, customProperties, logic,
|
|
|
13113
13115
|
});
|
|
13114
13116
|
let fieldSetFields;
|
|
13115
13117
|
if (fieldParams.inputType === supportedTypes.FIELDSET) {
|
|
13116
|
-
fieldSetFields = rebuildFieldset(
|
|
13118
|
+
fieldSetFields = rebuildFieldset(
|
|
13119
|
+
fieldParams.fields,
|
|
13120
|
+
currentField.fields,
|
|
13121
|
+
conditionalProperty
|
|
13122
|
+
);
|
|
13117
13123
|
newFieldParams.fields = fieldSetFields;
|
|
13118
13124
|
}
|
|
13119
13125
|
const { computedAttributes, ...restNewFieldParams } = newFieldParams;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remoteoss/json-schema-form",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.2-beta.0",
|
|
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",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
},
|
|
44
44
|
"lint-staged": {
|
|
45
45
|
"*.{js,jsx}": [
|
|
46
|
-
"npm run format"
|
|
46
|
+
"npm run format --prefix ./v0"
|
|
47
47
|
]
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
@@ -63,6 +63,7 @@ import {
|
|
|
63
63
|
schemaForErrorMessageSpecificity,
|
|
64
64
|
jsfConfigForErrorMessageSpecificity,
|
|
65
65
|
schemaInputTypeFile,
|
|
66
|
+
schemaWithNestedFieldsetsConditionals,
|
|
66
67
|
} from './helpers';
|
|
67
68
|
import { mockConsole, restoreConsoleAndEnsureItWasNotCalled } from './testUtils';
|
|
68
69
|
import { createHeadlessForm } from '@/createHeadlessForm';
|
|
@@ -2200,6 +2201,191 @@ describe('createHeadlessForm', () => {
|
|
|
2200
2201
|
).toBeUndefined();
|
|
2201
2202
|
});
|
|
2202
2203
|
});
|
|
2204
|
+
|
|
2205
|
+
describe('supports conditionals over nested fieldsets', () => {
|
|
2206
|
+
it('retirement_plan fieldset is hidden when no values are provided', () => {
|
|
2207
|
+
const { fields, handleValidation } = createHeadlessForm(
|
|
2208
|
+
schemaWithNestedFieldsetsConditionals,
|
|
2209
|
+
{}
|
|
2210
|
+
);
|
|
2211
|
+
const validateForm = (vals) => friendlyError(handleValidation(vals));
|
|
2212
|
+
|
|
2213
|
+
expect(getField(fields, 'perks', 'retirement_plan').isVisible).toBe(false);
|
|
2214
|
+
|
|
2215
|
+
expect(validateForm({ perks: {} })).toEqual({
|
|
2216
|
+
perks: {
|
|
2217
|
+
benefits_package: 'Required field',
|
|
2218
|
+
has_retirement_plan: 'Required field',
|
|
2219
|
+
},
|
|
2220
|
+
});
|
|
2221
|
+
|
|
2222
|
+
expect(getField(fields, 'perks', 'retirement_plan').isVisible).toBe(false);
|
|
2223
|
+
});
|
|
2224
|
+
|
|
2225
|
+
it("submits without retirement_plan when user selects 'no' for has_retirement_plan", () => {
|
|
2226
|
+
const { fields, handleValidation } = createHeadlessForm(
|
|
2227
|
+
schemaWithNestedFieldsetsConditionals,
|
|
2228
|
+
{}
|
|
2229
|
+
);
|
|
2230
|
+
const validateForm = (vals) => friendlyError(handleValidation(vals));
|
|
2231
|
+
|
|
2232
|
+
expect(
|
|
2233
|
+
validateForm({ perks: { benefits_package: 'basic', has_retirement_plan: 'no' } })
|
|
2234
|
+
).toBeUndefined();
|
|
2235
|
+
|
|
2236
|
+
expect(getField(fields, 'perks', 'retirement_plan').isVisible).toBe(false);
|
|
2237
|
+
});
|
|
2238
|
+
|
|
2239
|
+
it("retirement_plan fieldset is visible when user selects 'yes' for has_retirement_plan", () => {
|
|
2240
|
+
const { fields, handleValidation } = createHeadlessForm(
|
|
2241
|
+
schemaWithNestedFieldsetsConditionals,
|
|
2242
|
+
{}
|
|
2243
|
+
);
|
|
2244
|
+
const validateForm = (vals) => friendlyError(handleValidation(vals));
|
|
2245
|
+
|
|
2246
|
+
expect(
|
|
2247
|
+
validateForm({
|
|
2248
|
+
perks: {
|
|
2249
|
+
benefits_package: 'basic',
|
|
2250
|
+
has_retirement_plan: 'yes',
|
|
2251
|
+
declare_amount: 'yes',
|
|
2252
|
+
retirement_plan: { plan_name: 'test', year: 2025 },
|
|
2253
|
+
},
|
|
2254
|
+
})
|
|
2255
|
+
).toEqual({
|
|
2256
|
+
perks: {
|
|
2257
|
+
retirement_plan: {
|
|
2258
|
+
amount: 'Required field',
|
|
2259
|
+
},
|
|
2260
|
+
},
|
|
2261
|
+
});
|
|
2262
|
+
|
|
2263
|
+
expect(getField(fields, 'perks', 'retirement_plan').isVisible).toBe(true);
|
|
2264
|
+
expect(getField(fields, 'perks', 'declare_amount').isVisible).toBe(true);
|
|
2265
|
+
expect(getField(fields, 'perks', 'declare_amount').default).toBe('yes');
|
|
2266
|
+
expect(getField(fields, 'perks', 'retirement_plan', 'amount').isVisible).toBe(true);
|
|
2267
|
+
});
|
|
2268
|
+
|
|
2269
|
+
it("retirement_plan's amount field is hidden when user selects 'no' for declare_amount", () => {
|
|
2270
|
+
const { fields, handleValidation } = createHeadlessForm(
|
|
2271
|
+
schemaWithNestedFieldsetsConditionals,
|
|
2272
|
+
{}
|
|
2273
|
+
);
|
|
2274
|
+
const validateForm = (vals) => friendlyError(handleValidation(vals));
|
|
2275
|
+
|
|
2276
|
+
expect(
|
|
2277
|
+
validateForm({
|
|
2278
|
+
perks: {
|
|
2279
|
+
benefits_package: 'basic',
|
|
2280
|
+
has_retirement_plan: 'yes',
|
|
2281
|
+
declare_amount: 'no',
|
|
2282
|
+
retirement_plan: { plan_name: 'test', year: 2025 },
|
|
2283
|
+
},
|
|
2284
|
+
})
|
|
2285
|
+
).toBeUndefined();
|
|
2286
|
+
|
|
2287
|
+
expect(getField(fields, 'perks', 'retirement_plan').isVisible).toBe(true);
|
|
2288
|
+
expect(getField(fields, 'perks', 'declare_amount').isVisible).toBe(true);
|
|
2289
|
+
expect(getField(fields, 'perks', 'retirement_plan', 'amount').isVisible).toBe(false);
|
|
2290
|
+
});
|
|
2291
|
+
|
|
2292
|
+
it('submits with valid retirement_plan', async () => {
|
|
2293
|
+
const { handleValidation } = createHeadlessForm(
|
|
2294
|
+
schemaWithNestedFieldsetsConditionals,
|
|
2295
|
+
{}
|
|
2296
|
+
);
|
|
2297
|
+
const validateForm = (vals) => friendlyError(handleValidation(vals));
|
|
2298
|
+
|
|
2299
|
+
expect(
|
|
2300
|
+
validateForm({
|
|
2301
|
+
perks: {
|
|
2302
|
+
benefits_package: 'plus',
|
|
2303
|
+
has_retirement_plan: 'yes',
|
|
2304
|
+
retirement_plan: { plan_name: 'test', year: 2025, amount: 1000 },
|
|
2305
|
+
},
|
|
2306
|
+
})
|
|
2307
|
+
).toBeUndefined();
|
|
2308
|
+
});
|
|
2309
|
+
});
|
|
2310
|
+
|
|
2311
|
+
describe('supports computed values based on values from nested fieldsets', () => {
|
|
2312
|
+
it("computed value for total_contributions is calculated correctly with defaults when user selects 'yes' for has_retirement_plan", () => {
|
|
2313
|
+
const { fields, handleValidation } = createHeadlessForm(
|
|
2314
|
+
schemaWithNestedFieldsetsConditionals,
|
|
2315
|
+
{}
|
|
2316
|
+
);
|
|
2317
|
+
const validateForm = (vals) => friendlyError(handleValidation(vals));
|
|
2318
|
+
|
|
2319
|
+
expect(
|
|
2320
|
+
validateForm({
|
|
2321
|
+
perks: {
|
|
2322
|
+
benefits_package: 'basic',
|
|
2323
|
+
has_retirement_plan: 'yes',
|
|
2324
|
+
declare_amount: 'no',
|
|
2325
|
+
retirement_plan: {
|
|
2326
|
+
plan_name: 'test',
|
|
2327
|
+
create_plan: 'no',
|
|
2328
|
+
},
|
|
2329
|
+
},
|
|
2330
|
+
})
|
|
2331
|
+
).toEqual({ perks: { retirement_plan: { year: 'Required field' } } });
|
|
2332
|
+
|
|
2333
|
+
expect(getField(fields, 'total_contributions').isVisible).toBe(true);
|
|
2334
|
+
expect(getField(fields, 'total_contributions').default).toBe(0);
|
|
2335
|
+
expect(getField(fields, 'total_contributions').const).toBe(0);
|
|
2336
|
+
});
|
|
2337
|
+
|
|
2338
|
+
it('computed value for total_contributions is calculated correctly based on the selected months', () => {
|
|
2339
|
+
const { fields, handleValidation } = createHeadlessForm(
|
|
2340
|
+
schemaWithNestedFieldsetsConditionals,
|
|
2341
|
+
{}
|
|
2342
|
+
);
|
|
2343
|
+
const validateForm = (vals) => friendlyError(handleValidation(vals));
|
|
2344
|
+
|
|
2345
|
+
expect(
|
|
2346
|
+
validateForm({
|
|
2347
|
+
perks: {
|
|
2348
|
+
benefits_package: 'basic',
|
|
2349
|
+
has_retirement_plan: 'yes',
|
|
2350
|
+
declare_amount: 'no',
|
|
2351
|
+
retirement_plan: {
|
|
2352
|
+
plan_name: 'test',
|
|
2353
|
+
year: 2025,
|
|
2354
|
+
create_plan: 'yes',
|
|
2355
|
+
planned_contributions: {
|
|
2356
|
+
months: ['january', 'february', 'march', 'april', 'may'],
|
|
2357
|
+
},
|
|
2358
|
+
},
|
|
2359
|
+
},
|
|
2360
|
+
})
|
|
2361
|
+
).toBeUndefined();
|
|
2362
|
+
|
|
2363
|
+
expect(getField(fields, 'total_contributions').isVisible).toBe(true);
|
|
2364
|
+
expect(getField(fields, 'total_contributions').default).toBe(5);
|
|
2365
|
+
expect(getField(fields, 'total_contributions').const).toBe(5);
|
|
2366
|
+
|
|
2367
|
+
expect(
|
|
2368
|
+
validateForm({
|
|
2369
|
+
perks: {
|
|
2370
|
+
benefits_package: 'basic',
|
|
2371
|
+
has_retirement_plan: 'yes',
|
|
2372
|
+
declare_amount: 'no',
|
|
2373
|
+
retirement_plan: {
|
|
2374
|
+
plan_name: 'test',
|
|
2375
|
+
year: 2025,
|
|
2376
|
+
create_plan: 'yes',
|
|
2377
|
+
planned_contributions: {
|
|
2378
|
+
months: ['january', 'february', 'march'],
|
|
2379
|
+
},
|
|
2380
|
+
},
|
|
2381
|
+
},
|
|
2382
|
+
})
|
|
2383
|
+
).toBeUndefined();
|
|
2384
|
+
|
|
2385
|
+
expect(getField(fields, 'total_contributions').default).toBe(3);
|
|
2386
|
+
expect(getField(fields, 'total_contributions').const).toBe(3);
|
|
2387
|
+
});
|
|
2388
|
+
});
|
|
2203
2389
|
});
|
|
2204
2390
|
|
|
2205
2391
|
it('support "email" field type', () => {
|
package/src/tests/helpers.js
CHANGED
|
@@ -1939,7 +1939,6 @@ export const schemaWithConditionalToFieldset = {
|
|
|
1939
1939
|
then: {
|
|
1940
1940
|
properties: {
|
|
1941
1941
|
pto: {
|
|
1942
|
-
$comment: '@BUG: This description does not disappear once activated.',
|
|
1943
1942
|
description: 'Above 30 hours, the PTO needs to be at least 20 days.',
|
|
1944
1943
|
minimum: 20,
|
|
1945
1944
|
},
|
|
@@ -1972,6 +1971,389 @@ export const schemaWithConditionalToFieldset = {
|
|
|
1972
1971
|
required: ['perks', 'work_hours_per_week'],
|
|
1973
1972
|
};
|
|
1974
1973
|
|
|
1974
|
+
export const schemaWithNestedFieldsetsConditionals = {
|
|
1975
|
+
additionalProperties: false,
|
|
1976
|
+
type: 'object',
|
|
1977
|
+
properties: {
|
|
1978
|
+
perks: {
|
|
1979
|
+
additionalProperties: false,
|
|
1980
|
+
properties: {
|
|
1981
|
+
benefits_package: {
|
|
1982
|
+
oneOf: [
|
|
1983
|
+
{
|
|
1984
|
+
const: 'basic',
|
|
1985
|
+
title: 'Basic',
|
|
1986
|
+
},
|
|
1987
|
+
{
|
|
1988
|
+
const: 'plus',
|
|
1989
|
+
title: 'Plus',
|
|
1990
|
+
},
|
|
1991
|
+
],
|
|
1992
|
+
title: 'Benefits package',
|
|
1993
|
+
type: 'string',
|
|
1994
|
+
'x-jsf-presentation': {
|
|
1995
|
+
inputType: 'radio',
|
|
1996
|
+
},
|
|
1997
|
+
},
|
|
1998
|
+
has_retirement_plan: {
|
|
1999
|
+
oneOf: [
|
|
2000
|
+
{
|
|
2001
|
+
const: 'yes',
|
|
2002
|
+
title: 'Yes',
|
|
2003
|
+
},
|
|
2004
|
+
{
|
|
2005
|
+
const: 'no',
|
|
2006
|
+
title: 'No',
|
|
2007
|
+
},
|
|
2008
|
+
],
|
|
2009
|
+
title: 'Has retirement plan?',
|
|
2010
|
+
type: 'string',
|
|
2011
|
+
'x-jsf-presentation': {
|
|
2012
|
+
inputType: 'radio',
|
|
2013
|
+
},
|
|
2014
|
+
},
|
|
2015
|
+
declare_amount: {
|
|
2016
|
+
oneOf: [
|
|
2017
|
+
{
|
|
2018
|
+
const: 'yes',
|
|
2019
|
+
title: 'Yes',
|
|
2020
|
+
},
|
|
2021
|
+
{
|
|
2022
|
+
const: 'no',
|
|
2023
|
+
title: 'No',
|
|
2024
|
+
},
|
|
2025
|
+
],
|
|
2026
|
+
title: 'Declare planned retirement amount?',
|
|
2027
|
+
type: 'string',
|
|
2028
|
+
default: 'yes',
|
|
2029
|
+
'x-jsf-presentation': {
|
|
2030
|
+
inputType: 'radio',
|
|
2031
|
+
},
|
|
2032
|
+
},
|
|
2033
|
+
retirement_plan: {
|
|
2034
|
+
allOf: [
|
|
2035
|
+
{
|
|
2036
|
+
if: {
|
|
2037
|
+
properties: {
|
|
2038
|
+
create_plan: {
|
|
2039
|
+
const: 'yes',
|
|
2040
|
+
},
|
|
2041
|
+
},
|
|
2042
|
+
},
|
|
2043
|
+
then: {},
|
|
2044
|
+
else: {
|
|
2045
|
+
properties: {
|
|
2046
|
+
planned_contributions: false,
|
|
2047
|
+
},
|
|
2048
|
+
},
|
|
2049
|
+
},
|
|
2050
|
+
],
|
|
2051
|
+
type: 'object',
|
|
2052
|
+
title: 'Retirement plan',
|
|
2053
|
+
properties: {
|
|
2054
|
+
plan_name: {
|
|
2055
|
+
type: 'string',
|
|
2056
|
+
title: 'Plan name',
|
|
2057
|
+
},
|
|
2058
|
+
year: {
|
|
2059
|
+
type: 'number',
|
|
2060
|
+
title: 'Year',
|
|
2061
|
+
default: 2025,
|
|
2062
|
+
},
|
|
2063
|
+
amount: {
|
|
2064
|
+
type: 'number',
|
|
2065
|
+
title: 'Planned amount',
|
|
2066
|
+
},
|
|
2067
|
+
create_plan: {
|
|
2068
|
+
type: 'radio',
|
|
2069
|
+
title: 'Create plan?',
|
|
2070
|
+
oneOf: [
|
|
2071
|
+
{
|
|
2072
|
+
const: 'yes',
|
|
2073
|
+
title: 'Yes',
|
|
2074
|
+
},
|
|
2075
|
+
{
|
|
2076
|
+
const: 'no',
|
|
2077
|
+
title: 'No',
|
|
2078
|
+
},
|
|
2079
|
+
],
|
|
2080
|
+
default: 'yes',
|
|
2081
|
+
'x-jsf-presentation': {
|
|
2082
|
+
inputType: 'radio',
|
|
2083
|
+
},
|
|
2084
|
+
},
|
|
2085
|
+
planned_contributions: {
|
|
2086
|
+
type: 'object',
|
|
2087
|
+
title: 'Planned contributions',
|
|
2088
|
+
properties: {
|
|
2089
|
+
months: {
|
|
2090
|
+
default: ['january', 'february'],
|
|
2091
|
+
oneOf: [
|
|
2092
|
+
{
|
|
2093
|
+
const: 'january',
|
|
2094
|
+
title: 'January',
|
|
2095
|
+
},
|
|
2096
|
+
{
|
|
2097
|
+
const: 'february',
|
|
2098
|
+
title: 'February',
|
|
2099
|
+
},
|
|
2100
|
+
{
|
|
2101
|
+
const: 'march',
|
|
2102
|
+
title: 'March',
|
|
2103
|
+
},
|
|
2104
|
+
{
|
|
2105
|
+
const: 'april',
|
|
2106
|
+
title: 'April',
|
|
2107
|
+
},
|
|
2108
|
+
{
|
|
2109
|
+
const: 'may',
|
|
2110
|
+
title: 'May',
|
|
2111
|
+
},
|
|
2112
|
+
{
|
|
2113
|
+
const: 'june',
|
|
2114
|
+
title: 'June',
|
|
2115
|
+
},
|
|
2116
|
+
],
|
|
2117
|
+
title: "Select the months when you'll contribute",
|
|
2118
|
+
type: 'array',
|
|
2119
|
+
'x-jsf-presentation': {
|
|
2120
|
+
inputType: 'checkbox',
|
|
2121
|
+
},
|
|
2122
|
+
},
|
|
2123
|
+
},
|
|
2124
|
+
'x-jsf-presentation': {
|
|
2125
|
+
inputType: 'fieldset',
|
|
2126
|
+
},
|
|
2127
|
+
},
|
|
2128
|
+
},
|
|
2129
|
+
required: ['plan_name', 'year'],
|
|
2130
|
+
'x-jsf-presentation': {
|
|
2131
|
+
inputType: 'fieldset',
|
|
2132
|
+
},
|
|
2133
|
+
},
|
|
2134
|
+
},
|
|
2135
|
+
required: ['benefits_package', 'has_retirement_plan'],
|
|
2136
|
+
title: 'Perks',
|
|
2137
|
+
type: 'object',
|
|
2138
|
+
'x-jsf-presentation': {
|
|
2139
|
+
inputType: 'fieldset',
|
|
2140
|
+
},
|
|
2141
|
+
},
|
|
2142
|
+
total_contributions: {
|
|
2143
|
+
title: 'Total contributions',
|
|
2144
|
+
description: 'The total contributions for the retirement plan',
|
|
2145
|
+
type: 'number',
|
|
2146
|
+
'x-jsf-presentation': {
|
|
2147
|
+
inputType: 'number',
|
|
2148
|
+
},
|
|
2149
|
+
'x-jsf-logic-computedAttrs': {
|
|
2150
|
+
const: 'total_contributions',
|
|
2151
|
+
default: 'total_contributions',
|
|
2152
|
+
description: 'You will contribute {{total_contributions}} times this year',
|
|
2153
|
+
},
|
|
2154
|
+
},
|
|
2155
|
+
},
|
|
2156
|
+
allOf: [
|
|
2157
|
+
{
|
|
2158
|
+
if: {
|
|
2159
|
+
properties: {
|
|
2160
|
+
perks: {
|
|
2161
|
+
properties: {
|
|
2162
|
+
has_retirement_plan: {
|
|
2163
|
+
const: 'no',
|
|
2164
|
+
},
|
|
2165
|
+
},
|
|
2166
|
+
},
|
|
2167
|
+
},
|
|
2168
|
+
},
|
|
2169
|
+
then: {
|
|
2170
|
+
properties: {
|
|
2171
|
+
perks: {
|
|
2172
|
+
properties: {
|
|
2173
|
+
retirement_plan: false,
|
|
2174
|
+
declare_amount: false,
|
|
2175
|
+
},
|
|
2176
|
+
},
|
|
2177
|
+
},
|
|
2178
|
+
},
|
|
2179
|
+
},
|
|
2180
|
+
{
|
|
2181
|
+
if: {
|
|
2182
|
+
properties: {
|
|
2183
|
+
perks: {
|
|
2184
|
+
properties: {
|
|
2185
|
+
declare_amount: {
|
|
2186
|
+
const: 'no',
|
|
2187
|
+
},
|
|
2188
|
+
},
|
|
2189
|
+
required: ['declare_amount'],
|
|
2190
|
+
},
|
|
2191
|
+
},
|
|
2192
|
+
},
|
|
2193
|
+
then: {
|
|
2194
|
+
properties: {
|
|
2195
|
+
perks: {
|
|
2196
|
+
properties: {
|
|
2197
|
+
retirement_plan: {
|
|
2198
|
+
properties: {
|
|
2199
|
+
amount: false,
|
|
2200
|
+
},
|
|
2201
|
+
},
|
|
2202
|
+
},
|
|
2203
|
+
},
|
|
2204
|
+
},
|
|
2205
|
+
},
|
|
2206
|
+
},
|
|
2207
|
+
{
|
|
2208
|
+
if: {
|
|
2209
|
+
properties: {
|
|
2210
|
+
perks: {
|
|
2211
|
+
properties: {
|
|
2212
|
+
has_retirement_plan: {
|
|
2213
|
+
const: 'yes',
|
|
2214
|
+
},
|
|
2215
|
+
declare_amount: {
|
|
2216
|
+
const: 'yes',
|
|
2217
|
+
},
|
|
2218
|
+
},
|
|
2219
|
+
required: ['has_retirement_plan', 'declare_amount'],
|
|
2220
|
+
},
|
|
2221
|
+
},
|
|
2222
|
+
},
|
|
2223
|
+
then: {
|
|
2224
|
+
properties: {
|
|
2225
|
+
perks: {
|
|
2226
|
+
properties: {
|
|
2227
|
+
retirement_plan: {
|
|
2228
|
+
required: ['amount'],
|
|
2229
|
+
},
|
|
2230
|
+
},
|
|
2231
|
+
},
|
|
2232
|
+
},
|
|
2233
|
+
},
|
|
2234
|
+
},
|
|
2235
|
+
],
|
|
2236
|
+
'x-jsf-logic': {
|
|
2237
|
+
computedValues: {
|
|
2238
|
+
total_contributions: {
|
|
2239
|
+
rule: {
|
|
2240
|
+
if: [
|
|
2241
|
+
{
|
|
2242
|
+
and: [
|
|
2243
|
+
{
|
|
2244
|
+
'===': [
|
|
2245
|
+
{
|
|
2246
|
+
var: 'perks.has_retirement_plan',
|
|
2247
|
+
},
|
|
2248
|
+
'yes',
|
|
2249
|
+
],
|
|
2250
|
+
},
|
|
2251
|
+
{
|
|
2252
|
+
'===': [
|
|
2253
|
+
{
|
|
2254
|
+
var: 'perks.retirement_plan.create_plan',
|
|
2255
|
+
},
|
|
2256
|
+
'yes',
|
|
2257
|
+
],
|
|
2258
|
+
},
|
|
2259
|
+
],
|
|
2260
|
+
},
|
|
2261
|
+
{
|
|
2262
|
+
'+': [
|
|
2263
|
+
{
|
|
2264
|
+
if: [
|
|
2265
|
+
{
|
|
2266
|
+
in: [
|
|
2267
|
+
'january',
|
|
2268
|
+
{
|
|
2269
|
+
var: 'perks.retirement_plan.planned_contributions.months',
|
|
2270
|
+
},
|
|
2271
|
+
],
|
|
2272
|
+
},
|
|
2273
|
+
1,
|
|
2274
|
+
0,
|
|
2275
|
+
],
|
|
2276
|
+
},
|
|
2277
|
+
{
|
|
2278
|
+
if: [
|
|
2279
|
+
{
|
|
2280
|
+
in: [
|
|
2281
|
+
'february',
|
|
2282
|
+
{
|
|
2283
|
+
var: 'perks.retirement_plan.planned_contributions.months',
|
|
2284
|
+
},
|
|
2285
|
+
],
|
|
2286
|
+
},
|
|
2287
|
+
1,
|
|
2288
|
+
0,
|
|
2289
|
+
],
|
|
2290
|
+
},
|
|
2291
|
+
{
|
|
2292
|
+
if: [
|
|
2293
|
+
{
|
|
2294
|
+
in: [
|
|
2295
|
+
'march',
|
|
2296
|
+
{
|
|
2297
|
+
var: 'perks.retirement_plan.planned_contributions.months',
|
|
2298
|
+
},
|
|
2299
|
+
],
|
|
2300
|
+
},
|
|
2301
|
+
1,
|
|
2302
|
+
0,
|
|
2303
|
+
],
|
|
2304
|
+
},
|
|
2305
|
+
{
|
|
2306
|
+
if: [
|
|
2307
|
+
{
|
|
2308
|
+
in: [
|
|
2309
|
+
'april',
|
|
2310
|
+
{
|
|
2311
|
+
var: 'perks.retirement_plan.planned_contributions.months',
|
|
2312
|
+
},
|
|
2313
|
+
],
|
|
2314
|
+
},
|
|
2315
|
+
1,
|
|
2316
|
+
0,
|
|
2317
|
+
],
|
|
2318
|
+
},
|
|
2319
|
+
{
|
|
2320
|
+
if: [
|
|
2321
|
+
{
|
|
2322
|
+
in: [
|
|
2323
|
+
'may',
|
|
2324
|
+
{
|
|
2325
|
+
var: 'perks.retirement_plan.planned_contributions.months',
|
|
2326
|
+
},
|
|
2327
|
+
],
|
|
2328
|
+
},
|
|
2329
|
+
1,
|
|
2330
|
+
0,
|
|
2331
|
+
],
|
|
2332
|
+
},
|
|
2333
|
+
{
|
|
2334
|
+
if: [
|
|
2335
|
+
{
|
|
2336
|
+
in: [
|
|
2337
|
+
'june',
|
|
2338
|
+
{
|
|
2339
|
+
var: 'perks.retirement_plan.planned_contributions.months',
|
|
2340
|
+
},
|
|
2341
|
+
],
|
|
2342
|
+
},
|
|
2343
|
+
1,
|
|
2344
|
+
0,
|
|
2345
|
+
],
|
|
2346
|
+
},
|
|
2347
|
+
],
|
|
2348
|
+
},
|
|
2349
|
+
0,
|
|
2350
|
+
],
|
|
2351
|
+
},
|
|
2352
|
+
},
|
|
2353
|
+
},
|
|
2354
|
+
},
|
|
2355
|
+
};
|
|
2356
|
+
|
|
1975
2357
|
export const schemaWorkSchedule = {
|
|
1976
2358
|
type: 'object',
|
|
1977
2359
|
properties: {
|
|
File without changes
|