@ng-formworks/core 17.6.0 → 17.6.2
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/esm2022/lib/json-schema-form.component.mjs +4 -2
- package/esm2022/lib/json-schema-form.service.mjs +31 -11
- package/esm2022/lib/shared/form-group.functions.mjs +82 -15
- package/esm2022/lib/shared/json-schema.functions.mjs +28 -3
- package/esm2022/lib/shared/jsonpointer.functions.mjs +2 -2
- package/esm2022/lib/shared/layout.functions.mjs +65 -18
- package/esm2022/lib/widget-library/checkbox.component.mjs +9 -4
- package/esm2022/lib/widget-library/one-of.component.mjs +25 -9
- package/esm2022/lib/widget-library/root.component.mjs +58 -1
- package/fesm2022/ng-formworks-core.mjs +293 -54
- package/fesm2022/ng-formworks-core.mjs.map +1 -1
- package/lib/shared/form-group.functions.d.ts +2 -0
- package/lib/shared/json-schema.functions.d.ts +1 -1
- package/lib/shared/validator.functions.d.ts +1 -1
- package/lib/widget-library/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -10,7 +10,7 @@ import jsonDraft6 from 'ajv/lib/refs/json-schema-draft-06.json';
|
|
|
10
10
|
import jsonDraft7 from 'ajv/lib/refs/json-schema-draft-07.json';
|
|
11
11
|
import cloneDeep from 'lodash/cloneDeep';
|
|
12
12
|
import { from, Observable, forkJoin, Subject, BehaviorSubject, lastValueFrom } from 'rxjs';
|
|
13
|
-
import { some, isNil, isEmpty as isEmpty$1, isObject as isObject$1, isEqual as isEqual$2 } from 'lodash';
|
|
13
|
+
import { some, isNil, isEmpty as isEmpty$1, pick, isObject as isObject$1, isEqual as isEqual$2 } from 'lodash';
|
|
14
14
|
import isEqual$1 from 'lodash/isEqual';
|
|
15
15
|
import { map, takeUntil } from 'rxjs/operators';
|
|
16
16
|
import omit from 'lodash/omit';
|
|
@@ -4588,16 +4588,41 @@ function fixRequiredArrayProperties(schema) {
|
|
|
4588
4588
|
* @returns
|
|
4589
4589
|
|
|
4590
4590
|
*/
|
|
4591
|
-
function convertJSONSchemaIfToCondition(schema, negate = false) {
|
|
4591
|
+
function convertJSONSchemaIfToCondition(schema, layoutNode, negate = false) {
|
|
4592
4592
|
let conditionFun = "";
|
|
4593
4593
|
let condition = {};
|
|
4594
4594
|
let notOp = negate ? "!" : "";
|
|
4595
|
+
// expects "dataPointer" to be like "/a/b/c"
|
|
4596
|
+
//TODO-test
|
|
4597
|
+
//dataPointer can be something like /cities/-/name
|
|
4598
|
+
//must end up like model.cities[arrayIndices].name
|
|
4599
|
+
//also check can possibly be nested array like /cities/-/sites/-/siteName
|
|
4600
|
+
//in this case must probably end up like
|
|
4601
|
+
// /cities/arrayIndices[0]/sites/arrayIndices[1]/siteName
|
|
4602
|
+
//but it seems evaluatCondition support only one level for now
|
|
4603
|
+
//and uses arrayIndices as the last index only -check?
|
|
4604
|
+
let parentPath = layoutNode.dataPointer ? layoutNode.dataPointer
|
|
4605
|
+
.split("/")
|
|
4606
|
+
.slice(1, -1)
|
|
4607
|
+
.map((part, ind) => {
|
|
4608
|
+
let sep = ind == 0 ? "" : ".";
|
|
4609
|
+
let ret = part == "-" ? "[arrayIndices]" : sep + part;
|
|
4610
|
+
return ret;
|
|
4611
|
+
})
|
|
4612
|
+
.join("")
|
|
4613
|
+
: "";
|
|
4614
|
+
let modelPath = parentPath ? `model.${parentPath}` : "model";
|
|
4615
|
+
let checkPath = modelPath.split(".")
|
|
4616
|
+
.reduce((accumulator, currentPart, index) => {
|
|
4617
|
+
const currentExpression = index === 0 ? currentPart : `${accumulator}.${currentPart}`;
|
|
4618
|
+
return index === 0 ? currentExpression : `${accumulator} && ${currentExpression}`;
|
|
4619
|
+
}, '');
|
|
4595
4620
|
if (schema.if) {
|
|
4596
4621
|
Object.keys(schema.if.properties).forEach((ifProp, ind) => {
|
|
4597
4622
|
let amper = ind > 0 ? "&" : "";
|
|
4598
4623
|
//Note the model value is first converted to string and so is the condition
|
|
4599
4624
|
//so that booleans and numbers can also be compared
|
|
4600
|
-
conditionFun += `${amper}
|
|
4625
|
+
conditionFun += `${amper} ${checkPath} && ${modelPath}.${ifProp}+""=='${schema.if.properties[ifProp].const}'`;
|
|
4601
4626
|
});
|
|
4602
4627
|
}
|
|
4603
4628
|
condition["functionBody"] = `return ${notOp}(${conditionFun})`;
|
|
@@ -5088,7 +5113,8 @@ function buildFormGroupTemplate(jsf, nodeValue = null, setValues = true, schemaP
|
|
|
5088
5113
|
if (foundKeys && foundKeys.length > 0) {
|
|
5089
5114
|
const keySchemaPointer = `/${ofType}/${ind}`;
|
|
5090
5115
|
//console.log(`found:${keySchemaPointer}`);
|
|
5091
|
-
let newNodeValue = JsonPointer.get(nodeValue,
|
|
5116
|
+
let newNodeValue = JsonPointer.get(nodeValue, dataPointer);
|
|
5117
|
+
//JsonPointer.get(nodeValue, keySchemaPointer);
|
|
5092
5118
|
if (ofType == "oneOf") {
|
|
5093
5119
|
newNodeValue = nodeValue;
|
|
5094
5120
|
}
|
|
@@ -5115,16 +5141,52 @@ function buildFormGroupTemplate(jsf, nodeValue = null, setValues = true, schemaP
|
|
|
5115
5141
|
//if key is a $oneOf key then it was inserted at the root of the controls
|
|
5116
5142
|
//as form control name will be the full(escaped) path
|
|
5117
5143
|
const pointerPath = key.startsWith('$oneOf') ? controlItem.schemaPointer : keySchemaPointer;
|
|
5118
|
-
let oneOfItemSchema = JsonPointer.get(schema,
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5144
|
+
let oneOfItemSchema = JsonPointer.get(jsf.schema, controlItem.schemaPointer);
|
|
5145
|
+
//JsonPointer.get(schema,pointerPath);
|
|
5146
|
+
let dPointer = controlItem.schemaPointer.replace(/(anyOf|allOf|oneOf|none)\/[\d]+\//g, '')
|
|
5147
|
+
.replace(/(if|then|else|properties)\//g, '');
|
|
5148
|
+
//JsonPointer.toDataPointer(controlItem.schemaPointer,jsf.schema);
|
|
5149
|
+
let dVal = JsonPointer.get(nodeValue, dPointer);
|
|
5150
|
+
let fkey = key;
|
|
5151
|
+
let oneOfItemValue = dVal;
|
|
5152
|
+
/*
|
|
5153
|
+
if(hasOwn(oneOfItemSchema,"if") && controlItem.schemaPointer
|
|
5154
|
+
&& controlItem.schemaPointer.indexOf(keySchemaPointer)==0){
|
|
5155
|
+
let parts=controlItem.schemaPointer
|
|
5156
|
+
.split(keySchemaPointer).join('').split("/")
|
|
5157
|
+
let thenOrElse=parts[1];
|
|
5158
|
+
fkey=parts[parts.length-1];
|
|
5159
|
+
oneOfItemSchema=oneOfItemSchema[thenOrElse];
|
|
5160
|
+
}
|
|
5161
|
+
|
|
5162
|
+
if(oneOfItemSchema.properties && jsf.formValues===undefined){
|
|
5163
|
+
//check if no form data values were supplied
|
|
5164
|
+
//then set it to default otherwise to its nodevalue
|
|
5165
|
+
oneOfItemValue=oneOfItemSchema.default
|
|
5166
|
+
oneOfItemValue[fkey]=oneOfItemSchema.properties[fkey]?.default;
|
|
5167
|
+
}
|
|
5168
|
+
if(oneOfItemSchema.properties && jsf.formValues!=undefined){
|
|
5169
|
+
oneOfItemValue ={};
|
|
5170
|
+
//nodeValue||{};
|
|
5171
|
+
oneOfItemValue[fkey]=nodeValue&&nodeValue[fkey];
|
|
5172
|
+
}
|
|
5173
|
+
if(!oneOfItemSchema.properties && jsf.formValues==undefined){
|
|
5174
|
+
oneOfItemValue=oneOfItemSchema.default;
|
|
5175
|
+
}
|
|
5176
|
+
*/
|
|
5177
|
+
if (hasOwn(controlItem, "value")) {
|
|
5178
|
+
if (!jsf.ajv.validate(oneOfItemSchema, oneOfItemValue)) {
|
|
5179
|
+
controlItem.value.value = null;
|
|
5180
|
+
}
|
|
5181
|
+
else {
|
|
5182
|
+
///controlItem.value.value=oneOfItemValue[fkey];
|
|
5183
|
+
controlItem.value.value = oneOfItemSchema.properties ? oneOfItemValue[fkey] : oneOfItemValue;
|
|
5184
|
+
}
|
|
5123
5185
|
}
|
|
5124
5186
|
//controls[controlKey] = controlItem;
|
|
5125
5187
|
//allOfFGTemplate.controls[key].schemaPointer ||`${schemaPointer}${keySchemaPointer}/${key}`;
|
|
5126
5188
|
//allOfFGTemplate.controls[key].schemaPointer || schemaPointer + keySchemaPointer;
|
|
5127
|
-
controls[key] = cloneDeep(allOfFGTemplate.controls[key]);
|
|
5189
|
+
///////controls[key] = cloneDeep(allOfFGTemplate.controls[key]);
|
|
5128
5190
|
//add schemacontrol to root
|
|
5129
5191
|
//controls[controlKey]=controlItem
|
|
5130
5192
|
controls[`_${ofType}`] = controls[`_${ofType}`] || {};
|
|
@@ -5138,7 +5200,7 @@ function buildFormGroupTemplate(jsf, nodeValue = null, setValues = true, schemaP
|
|
|
5138
5200
|
});
|
|
5139
5201
|
jsf.formOptions.fieldsRequired = setRequiredFields(schema, controls);
|
|
5140
5202
|
}
|
|
5141
|
-
return { controlType, controls, validators };
|
|
5203
|
+
return { controlType, controls, validators, schemaPointer };
|
|
5142
5204
|
case 'FormArray':
|
|
5143
5205
|
controls = [];
|
|
5144
5206
|
const minItems = Math.max(schema.minItems || 0, nodeOptions.get('minItems') || 0);
|
|
@@ -5195,7 +5257,7 @@ function buildFormGroupTemplate(jsf, nodeValue = null, setValues = true, schemaP
|
|
|
5195
5257
|
}
|
|
5196
5258
|
}
|
|
5197
5259
|
}
|
|
5198
|
-
return { controlType, controls, validators };
|
|
5260
|
+
return { controlType, controls, validators, schemaPointer };
|
|
5199
5261
|
case '$ref':
|
|
5200
5262
|
const schemaRef = JsonPointer.compile(schema.$ref);
|
|
5201
5263
|
const dataRef = JsonPointer.toDataPointer(schemaRef, schema);
|
|
@@ -5217,7 +5279,7 @@ function buildFormGroupTemplate(jsf, nodeValue = null, setValues = true, schemaP
|
|
|
5217
5279
|
value: setValues && isPrimitive(nodeValue) ? nodeValue : null,
|
|
5218
5280
|
disabled: nodeOptions.get('disabled') || false
|
|
5219
5281
|
};
|
|
5220
|
-
return { controlType, value, validators };
|
|
5282
|
+
return { controlType, value, validators, schemaPointer };
|
|
5221
5283
|
//TODO may make an IFThenElse widget or integrate it with the section
|
|
5222
5284
|
//widget
|
|
5223
5285
|
case 'IfThenElse':
|
|
@@ -5230,17 +5292,44 @@ function buildFormGroupTemplate(jsf, nodeValue = null, setValues = true, schemaP
|
|
|
5230
5292
|
let thenTFGTemplate = buildFormGroupTemplate(jsf, nodeValue, false, schemaPointer + keySchemaPointer, dataPointer, templatePointer + `/controls/${con}`);
|
|
5231
5293
|
//NB same property can be in both then and else
|
|
5232
5294
|
//so key must be the unique path to control
|
|
5295
|
+
//let ifItemSchema=JsonPointer.get(schema,keySchemaPointer);
|
|
5296
|
+
//let ifItemValue;
|
|
5233
5297
|
Object.keys(thenTFGTemplate.controls).forEach(key => {
|
|
5234
|
-
let controlKey = thenTFGTemplate.controls[key].schemaPointer
|
|
5298
|
+
let controlKey = thenTFGTemplate.controls[key].schemaPointer;
|
|
5299
|
+
////let controlItem=cloneDeep(thenTFGTemplate.controls[key]);
|
|
5300
|
+
////thenTFGTemplate.controls[key].schemaPointer || `${schemaPointer}${keySchemaPointer}/${key}`;
|
|
5235
5301
|
controlKey = path2ControlKey(controlKey);
|
|
5236
5302
|
let cItem = Object.assign({}, thenTFGTemplate.controls[key]);
|
|
5237
|
-
cItem.schemaPointer = `${schemaPointer}${keySchemaPointer}/${key}`;
|
|
5303
|
+
////cItem.schemaPointer = `${schemaPointer}${keySchemaPointer}/${key}`;
|
|
5304
|
+
/*
|
|
5305
|
+
if(ifItemSchema.properties && jsf.formValues===undefined){
|
|
5306
|
+
//check if no form data values were supplied
|
|
5307
|
+
//then set it to default otherwise to its nodevalue
|
|
5308
|
+
ifItemValue=ifItemSchema.default
|
|
5309
|
+
ifItemValue[key]=ifItemSchema.properties[key]?.default;
|
|
5310
|
+
}
|
|
5311
|
+
if(ifItemSchema.properties && jsf.formValues!=undefined){
|
|
5312
|
+
ifItemValue ={};
|
|
5313
|
+
//nodeValue||{};
|
|
5314
|
+
ifItemValue[key]=nodeValue&&nodeValue[key];
|
|
5315
|
+
}
|
|
5316
|
+
if(!ifItemSchema.properties && jsf.formValues==undefined){
|
|
5317
|
+
ifItemValue=ifItemSchema.default;
|
|
5318
|
+
}
|
|
5319
|
+
if(hasOwn(cItem,"value")){
|
|
5320
|
+
if(!jsf.ajv.validate(ifItemSchema,ifItemValue)){
|
|
5321
|
+
cItem.value.value=null;
|
|
5322
|
+
}else{
|
|
5323
|
+
cItem.value.value=ifItemValue[key];
|
|
5324
|
+
}
|
|
5325
|
+
}
|
|
5326
|
+
*/
|
|
5238
5327
|
controls[controlKey] = cItem;
|
|
5239
5328
|
});
|
|
5240
5329
|
}
|
|
5241
5330
|
});
|
|
5242
5331
|
}
|
|
5243
|
-
return { controlType, controls, validators };
|
|
5332
|
+
return { controlType, controls, validators, schemaPointer };
|
|
5244
5333
|
default:
|
|
5245
5334
|
return null;
|
|
5246
5335
|
}
|
|
@@ -5438,7 +5527,7 @@ function formatFormData(formData, dataMap, recursiveRefMap, arrayMap, returnEmpt
|
|
|
5438
5527
|
}
|
|
5439
5528
|
else if (typeof value !== 'object' || isDate(value) ||
|
|
5440
5529
|
(value === null && returnEmptyFields)) {
|
|
5441
|
-
if (genericPointer.
|
|
5530
|
+
if (genericPointer.indexOf("/$") >= 0) {
|
|
5442
5531
|
return formattedData;
|
|
5443
5532
|
}
|
|
5444
5533
|
console.error('formatFormData error: ' +
|
|
@@ -5512,6 +5601,9 @@ function getControl(formGroup, dataPointer, returnGroup = false, schemaPointer)
|
|
|
5512
5601
|
else if (hasOwn(subGroup, key)) {
|
|
5513
5602
|
subGroup = subGroup[key];
|
|
5514
5603
|
}
|
|
5604
|
+
else if (schemaPointer && hasOwn(subGroup, path2ControlKey(schemaPointer))) {
|
|
5605
|
+
subGroup = subGroup[path2ControlKey(schemaPointer)];
|
|
5606
|
+
}
|
|
5515
5607
|
else {
|
|
5516
5608
|
console.error(`getControl error: Unable to find "${key}" item in FormGroup.`);
|
|
5517
5609
|
console.error(dataPointer);
|
|
@@ -5752,7 +5844,6 @@ function buildLayout_original(jsf, widgetLibrary) {
|
|
|
5752
5844
|
schemaPointer = JsonPointer.toSchemaPointer(shortDataPointer, jsf.schema);
|
|
5753
5845
|
nodeDataMap.set('schemaPointer', schemaPointer);
|
|
5754
5846
|
}
|
|
5755
|
-
nodeDataMap.set('disabled', !!newNode.options.disabled);
|
|
5756
5847
|
nodeSchema = JsonPointer.get(jsf.schema, schemaPointer);
|
|
5757
5848
|
if (nodeSchema) {
|
|
5758
5849
|
if (!hasOwn(newNode, 'type')) {
|
|
@@ -5773,6 +5864,7 @@ function buildLayout_original(jsf, widgetLibrary) {
|
|
|
5773
5864
|
newNode.dataType =
|
|
5774
5865
|
nodeSchema.type || (hasOwn(nodeSchema, '$ref') ? '$ref' : null);
|
|
5775
5866
|
updateInputOptions(newNode, nodeSchema, jsf);
|
|
5867
|
+
nodeDataMap.set('disabled', !!newNode.options.disabled);
|
|
5776
5868
|
// Present checkboxes as single control, rather than array
|
|
5777
5869
|
if (newNode.type === 'checkboxes' && hasOwn(nodeSchema, 'items')) {
|
|
5778
5870
|
updateInputOptions(newNode, nodeSchema.items, jsf);
|
|
@@ -6196,6 +6288,37 @@ function fixNestedArrayLayout(options) {
|
|
|
6196
6288
|
* //
|
|
6197
6289
|
*/
|
|
6198
6290
|
function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPointer = '', dataPointer = '', arrayItem = false, arrayItemType = null, removable = null, forRefLibrary = false, dataPointerPrefix = '', jsonSchema) {
|
|
6291
|
+
function applyITEConditions(builtLayout, schPointer, keySchemaPointer, negateClause, parentLayout) {
|
|
6292
|
+
if (builtLayout) {
|
|
6293
|
+
if (parentLayout && parentLayout.isITEItem && parentLayout.options.condition) {
|
|
6294
|
+
return;
|
|
6295
|
+
}
|
|
6296
|
+
if (isArray(builtLayout)) {
|
|
6297
|
+
builtLayout.forEach(item => {
|
|
6298
|
+
item.isITEItem = true;
|
|
6299
|
+
item.options.condition = convertJSONSchemaIfToCondition(schema, item, negateClause);
|
|
6300
|
+
applyITEConditions(item, schPointer, keySchemaPointer, negateClause, builtLayout);
|
|
6301
|
+
//item.schemaPointer = schPointer + keySchemaPointer + item.dataPointer;
|
|
6302
|
+
//item.options.condition = convertJSONSchemaIfToCondition(schema, negateClause);
|
|
6303
|
+
//newSection.push(item);
|
|
6304
|
+
});
|
|
6305
|
+
}
|
|
6306
|
+
else if (hasOwn(builtLayout, "items")) {
|
|
6307
|
+
applyITEConditions(builtLayout.items, schPointer, keySchemaPointer, negateClause, builtLayout);
|
|
6308
|
+
// builtLayout.items.forEach(item => {
|
|
6309
|
+
// item.isITEItem=true;
|
|
6310
|
+
// item.options.condition = convertJSONSchemaIfToCondition(schema,item, negateClause);
|
|
6311
|
+
// applyITEConditions(item,schPointer,keySchemaPointer,negateClause)
|
|
6312
|
+
// });
|
|
6313
|
+
}
|
|
6314
|
+
else {
|
|
6315
|
+
builtLayout.isITEItem = true;
|
|
6316
|
+
//builtLayout.schemaPointer = `${schPointer}${keySchemaPointer}/${builtLayout.name}`;
|
|
6317
|
+
builtLayout.options.condition = convertJSONSchemaIfToCondition(schema, builtLayout, negateClause);
|
|
6318
|
+
//newSection.push(builtLayout)
|
|
6319
|
+
}
|
|
6320
|
+
}
|
|
6321
|
+
}
|
|
6199
6322
|
const jsSchema = jsonSchema || jsf.schema;
|
|
6200
6323
|
const schema = JsonPointer.get(jsSchema, schemaPointer);
|
|
6201
6324
|
//JsonPointer.get(jsf.schema, schemaPointer);
|
|
@@ -6233,6 +6356,7 @@ function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPoint
|
|
|
6233
6356
|
if (!jsf.dataMap.has(shortDataPointer)) {
|
|
6234
6357
|
jsf.dataMap.set(shortDataPointer, new Map());
|
|
6235
6358
|
}
|
|
6359
|
+
updateInputOptions(newNode, schema, jsf);
|
|
6236
6360
|
const nodeDataMap = jsf.dataMap.get(shortDataPointer);
|
|
6237
6361
|
if (!nodeDataMap.has('inputType')) {
|
|
6238
6362
|
nodeDataMap.set('schemaPointer', schemaPointer);
|
|
@@ -6240,7 +6364,7 @@ function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPoint
|
|
|
6240
6364
|
nodeDataMap.set('widget', newNode.widget);
|
|
6241
6365
|
nodeDataMap.set('disabled', !!newNode.options.disabled);
|
|
6242
6366
|
}
|
|
6243
|
-
updateInputOptions(newNode, schema, jsf);
|
|
6367
|
+
//updateInputOptions(newNode, schema, jsf);
|
|
6244
6368
|
if (!newNode.options.title && newNode.name && !/^\d+$/.test(newNode.name)) {
|
|
6245
6369
|
newNode.options.title = fixTitle(newNode.name);
|
|
6246
6370
|
}
|
|
@@ -6268,6 +6392,7 @@ function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPoint
|
|
|
6268
6392
|
'/properties/' + key : '/additionalProperties';
|
|
6269
6393
|
const innerItem = buildLayoutFromSchema(jsf, widgetLibrary, isObject(nodeValue) ? nodeValue[key] : null, schemaPointer + keySchemaPointer, dataPointer + '/' + key, false, null, null, forRefLibrary, dataPointerPrefix);
|
|
6270
6394
|
if (innerItem) {
|
|
6395
|
+
innerItem.schemaPointer = schemaPointer + keySchemaPointer;
|
|
6271
6396
|
if (isInputRequired(schema, '/' + key)) {
|
|
6272
6397
|
innerItem.options.required = true;
|
|
6273
6398
|
jsf.fieldsRequired = true;
|
|
@@ -6292,38 +6417,50 @@ function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPoint
|
|
|
6292
6417
|
}
|
|
6293
6418
|
schema[ofType].forEach((ofItem, ind) => {
|
|
6294
6419
|
const keySchemaPointer = `/${ofType}/${ind}`;
|
|
6295
|
-
const innerItem = buildLayoutFromSchema(jsf, widgetLibrary, ofItem, schemaPointer + keySchemaPointer, dataPointer, false, null, null, forRefLibrary
|
|
6420
|
+
const innerItem = buildLayoutFromSchema(jsf, widgetLibrary, ofItem, schemaPointer + keySchemaPointer, dataPointer, false, null, null, ofType == "oneOf" /*forRefLibrary*/, dataPointerPrefix);
|
|
6296
6421
|
if (innerItem) {
|
|
6297
6422
|
//newSection.push(innerItem);
|
|
6298
6423
|
if (innerItem.items) {
|
|
6299
6424
|
innerItem.items.forEach(innerItemLevel2 => {
|
|
6300
6425
|
const l2SchemaPointer = hasOwn(ofItem, 'properties') ?
|
|
6301
6426
|
'/properties/' + innerItemLevel2.name : innerItemLevel2.name;
|
|
6302
|
-
innerItemLevel2.oneOfPointer =
|
|
6303
|
-
innerItemLevel2.schemaPointer
|
|
6427
|
+
//innerItemLevel2.oneOfPointer = schemaPointer + keySchemaPointer + l2SchemaPointer;
|
|
6428
|
+
// innerItemLevel2.schemaPointer=innerItemLevel2.schemaPointer;
|
|
6429
|
+
innerItemLevel2.oneOfPointer = innerItemLevel2.schemaPointer;
|
|
6304
6430
|
});
|
|
6305
6431
|
}
|
|
6432
|
+
//TODO review-will never reach here if forRefLibrary==true
|
|
6306
6433
|
if (isArray(innerItem)) {
|
|
6434
|
+
let outerOneOfItemTpl = cloneDeep(newNode);
|
|
6435
|
+
outerOneOfItemTpl;
|
|
6307
6436
|
innerItem.forEach(item => {
|
|
6308
6437
|
const l2SchemaPointer = hasOwn(ofItem, 'properties') ?
|
|
6309
6438
|
'/properties/' + item.name : item.name;
|
|
6310
6439
|
if (outerOneOfItem) {
|
|
6311
|
-
item.oneOfPointer =
|
|
6440
|
+
////item.oneOfPointer = schemaPointer + keySchemaPointer + l2SchemaPointer;
|
|
6312
6441
|
//schemaPointer + keySchemaPointer + item.dataPointer;
|
|
6313
|
-
item.schemaPointer
|
|
6314
|
-
|
|
6442
|
+
////item.schemaPointer=item.oneOfPointer;
|
|
6443
|
+
/*
|
|
6444
|
+
outerOneOfItem.items=outerOneOfItem.items||[];
|
|
6315
6445
|
outerOneOfItem.items.push(item);
|
|
6446
|
+
*/
|
|
6447
|
+
outerOneOfItemTpl.items = outerOneOfItemTpl.items || [];
|
|
6448
|
+
outerOneOfItemTpl.items.push(item);
|
|
6316
6449
|
}
|
|
6317
6450
|
else {
|
|
6318
6451
|
newSection.push(item);
|
|
6319
6452
|
}
|
|
6320
6453
|
});
|
|
6454
|
+
if (outerOneOfItem) {
|
|
6455
|
+
outerOneOfItem.items = outerOneOfItem.items || [];
|
|
6456
|
+
outerOneOfItem.items.push(outerOneOfItemTpl);
|
|
6457
|
+
}
|
|
6321
6458
|
//TODO test-might not work for more than 2 levels of nesting
|
|
6322
6459
|
}
|
|
6323
6460
|
else {
|
|
6324
6461
|
if (outerOneOfItem) {
|
|
6325
6462
|
innerItem.oneOfPointer = schemaPointer + keySchemaPointer; // + innerItem.dataPointer;
|
|
6326
|
-
innerItem.schemaPointer
|
|
6463
|
+
////innerItem.schemaPointer=innerItem.oneOfPointer;
|
|
6327
6464
|
outerOneOfItem.items = outerOneOfItem.items || [];
|
|
6328
6465
|
outerOneOfItem.items.push(innerItem);
|
|
6329
6466
|
}
|
|
@@ -6342,16 +6479,17 @@ function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPoint
|
|
|
6342
6479
|
const negateClause = con == "else";
|
|
6343
6480
|
const innerItem = buildLayoutFromSchema(jsf, widgetLibrary, nodeValue.then, schemaPointer + keySchemaPointer, dataPointer, false, null, null, forRefLibrary, dataPointerPrefix);
|
|
6344
6481
|
if (innerItem) {
|
|
6482
|
+
applyITEConditions(innerItem, schemaPointer, keySchemaPointer, negateClause);
|
|
6345
6483
|
if (isArray(innerItem)) {
|
|
6346
6484
|
innerItem.forEach(item => {
|
|
6347
|
-
item.schemaPointer = schemaPointer + keySchemaPointer + item.dataPointer;
|
|
6348
|
-
item.options.condition = convertJSONSchemaIfToCondition(schema, negateClause);
|
|
6485
|
+
//item.schemaPointer = schemaPointer + keySchemaPointer + item.dataPointer;
|
|
6486
|
+
//item.options.condition = convertJSONSchemaIfToCondition(schema, negateClause);
|
|
6349
6487
|
newSection.push(item);
|
|
6350
6488
|
});
|
|
6351
6489
|
}
|
|
6352
6490
|
else {
|
|
6353
|
-
innerItem.schemaPointer = schemaPointer + keySchemaPointer + innerItem.dataPointer;
|
|
6354
|
-
innerItem.options.condition = convertJSONSchemaIfToCondition(schema, negateClause);
|
|
6491
|
+
//innerItem.schemaPointer = schemaPointer + keySchemaPointer + innerItem.dataPointer;
|
|
6492
|
+
//innerItem.options.condition = convertJSONSchemaIfToCondition(schema, negateClause);
|
|
6355
6493
|
newSection.push(innerItem);
|
|
6356
6494
|
}
|
|
6357
6495
|
}
|
|
@@ -6568,17 +6706,18 @@ function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPoint
|
|
|
6568
6706
|
const negateClause = con == "else";
|
|
6569
6707
|
const innerItem = buildLayoutFromSchema(jsf, widgetLibrary, nodeValue.then, schemaPointer + keySchemaPointer, dataPointer, false, null, null, forRefLibrary, dataPointerPrefix);
|
|
6570
6708
|
if (innerItem) {
|
|
6709
|
+
applyITEConditions(innerItem, schemaPointer, keySchemaPointer, negateClause);
|
|
6571
6710
|
if (isArray(innerItem)) {
|
|
6572
6711
|
innerItem.forEach(item => {
|
|
6573
|
-
item.schemaPointer = schemaPointer + keySchemaPointer + item.dataPointer;
|
|
6574
|
-
item.options.condition = convertJSONSchemaIfToCondition(schema, negateClause);
|
|
6712
|
+
//item.schemaPointer = schemaPointer + keySchemaPointer + item.dataPointer;
|
|
6713
|
+
//item.options.condition = convertJSONSchemaIfToCondition(schema, negateClause);
|
|
6575
6714
|
newSection.push(item);
|
|
6576
6715
|
newNode = newSection;
|
|
6577
6716
|
});
|
|
6578
6717
|
}
|
|
6579
6718
|
else {
|
|
6580
|
-
innerItem.schemaPointer = schemaPointer + keySchemaPointer + innerItem.dataPointer;
|
|
6581
|
-
innerItem.options.condition = convertJSONSchemaIfToCondition(schema, negateClause);
|
|
6719
|
+
//innerItem.schemaPointer = schemaPointer + keySchemaPointer + innerItem.dataPointer;
|
|
6720
|
+
//innerItem.options.condition = convertJSONSchemaIfToCondition(schema, negateClause);
|
|
6582
6721
|
newNode = innerItem;
|
|
6583
6722
|
}
|
|
6584
6723
|
}
|
|
@@ -7328,7 +7467,8 @@ class JsonSchemaFormService {
|
|
|
7328
7467
|
ctx.formControl = this.getFormControl(ctx);
|
|
7329
7468
|
//introduced to check if the node is part of ITE conditional
|
|
7330
7469
|
//then change or add the control
|
|
7331
|
-
if (layoutNode?.schemaPointer
|
|
7470
|
+
if (layoutNode?.schemaPointer && layoutNode.isITEItem ||
|
|
7471
|
+
(layoutNode?.schemaPointer && layoutNode?.oneOfPointer)) {
|
|
7332
7472
|
//before changing control, need to set the new data type for data formatting
|
|
7333
7473
|
const schemaType = this.dataMap.get(layoutNode?.dataPointer).get("schemaType");
|
|
7334
7474
|
if (schemaType != layoutNode.dataType) {
|
|
@@ -7369,11 +7509,24 @@ class JsonSchemaFormService {
|
|
|
7369
7509
|
}
|
|
7370
7510
|
//if this is a ITE conditional field, the value would not have been
|
|
7371
7511
|
//set, as the control would only be initialized when the condition is true
|
|
7372
|
-
|
|
7373
|
-
|
|
7374
|
-
|
|
7375
|
-
|
|
7376
|
-
ctx.formControl
|
|
7512
|
+
//TODO-review need to decide which of the data sets between data,formValues and default
|
|
7513
|
+
//to use for the value
|
|
7514
|
+
if (ctx.options?.condition || layoutNode?.oneOfPointer) {
|
|
7515
|
+
const dataPointer = this.getDataPointer(ctx);
|
|
7516
|
+
const controlValue = ctx.formControl.value;
|
|
7517
|
+
const dataValue = JsonPointer.has(this.data, dataPointer) ?
|
|
7518
|
+
JsonPointer.get(this.data, dataPointer) : undefined;
|
|
7519
|
+
const formValue = JsonPointer.has(this.formValues, dataPointer) ?
|
|
7520
|
+
JsonPointer.get(this.formValues, dataPointer) : undefined;
|
|
7521
|
+
const schemaDefault = ctx.options?.default;
|
|
7522
|
+
//if initial formValues was supplied and controlValue matches formValue then likely
|
|
7523
|
+
//control was initially created with the formValue then set value to data value
|
|
7524
|
+
//if no formValues was supplied and controlValue matches schemaDefault then likely
|
|
7525
|
+
//control was initially created with the default then set value to data value
|
|
7526
|
+
const value = this.formValues && isEqual$1(formValue, controlValue) ? dataValue
|
|
7527
|
+
: !this.formValues && isEqual$1(schemaDefault, controlValue) ? dataValue
|
|
7528
|
+
: schemaDefault;
|
|
7529
|
+
ctx.formControl?.patchValue(value);
|
|
7377
7530
|
}
|
|
7378
7531
|
return ctx.boundControl;
|
|
7379
7532
|
}
|
|
@@ -7489,7 +7642,9 @@ class JsonSchemaFormService {
|
|
|
7489
7642
|
ctx.layoutNode().type === '$ref') {
|
|
7490
7643
|
return null;
|
|
7491
7644
|
}
|
|
7492
|
-
|
|
7645
|
+
const schemaPointer = ctx.layoutNode()?.isITEItem ? ctx.layoutNode()?.schemaPointer : null;
|
|
7646
|
+
const oneOfPointer = ctx.layoutNode()?.oneOfPointer;
|
|
7647
|
+
return getControl(this.formGroup, this.getDataPointer(ctx), false, schemaPointer || oneOfPointer);
|
|
7493
7648
|
}
|
|
7494
7649
|
setFormControl(ctx, control) {
|
|
7495
7650
|
if (!ctx || !ctx.layoutNode ||
|
|
@@ -7505,14 +7660,18 @@ class JsonSchemaFormService {
|
|
|
7505
7660
|
ctx.layoutNode().type === '$ref') {
|
|
7506
7661
|
return null;
|
|
7507
7662
|
}
|
|
7508
|
-
const
|
|
7663
|
+
const schemaPointer = ctx.layoutNode()?.isITEItem ? ctx.layoutNode()?.schemaPointer : null;
|
|
7664
|
+
const oneOfPointer = ctx.layoutNode()?.oneOfPointer;
|
|
7665
|
+
const control = getControl(this.formGroup, this.getDataPointer(ctx), false, schemaPointer || oneOfPointer);
|
|
7509
7666
|
return control ? control.value : null;
|
|
7510
7667
|
}
|
|
7511
7668
|
getFormControlGroup(ctx) {
|
|
7512
7669
|
if (!ctx || !ctx.layoutNode || !isDefined(ctx.layoutNode().dataPointer)) {
|
|
7513
7670
|
return null;
|
|
7514
7671
|
}
|
|
7515
|
-
|
|
7672
|
+
const schemaPointer = ctx.layoutNode()?.isITEItem ? ctx.layoutNode()?.schemaPointer : null;
|
|
7673
|
+
const oneOfPointer = ctx.layoutNode()?.oneOfPointer;
|
|
7674
|
+
return getControl(this.formGroup, this.getDataPointer(ctx), true, schemaPointer || oneOfPointer);
|
|
7516
7675
|
}
|
|
7517
7676
|
getFormControlName(ctx) {
|
|
7518
7677
|
if (!ctx || !ctx.layoutNode ||
|
|
@@ -7862,6 +8021,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
7862
8021
|
}]
|
|
7863
8022
|
}] });
|
|
7864
8023
|
|
|
8024
|
+
///NB issue caused by sortablejs when it its destroyed
|
|
8025
|
+
//this mainly affects checkboxes coupled with conditions
|
|
8026
|
+
//-the value is rechecked
|
|
8027
|
+
//-see https://github.com/SortableJS/Sortable/issues/1052#issuecomment-369613072
|
|
7865
8028
|
class CheckboxComponent {
|
|
7866
8029
|
constructor() {
|
|
7867
8030
|
this.jsf = inject(JsonSchemaFormService);
|
|
@@ -7877,7 +8040,8 @@ class CheckboxComponent {
|
|
|
7877
8040
|
this.options = this.layoutNode().options || {};
|
|
7878
8041
|
this.jsf.initializeControl(this);
|
|
7879
8042
|
if (this.controlValue === null || this.controlValue === undefined) {
|
|
7880
|
-
this.controlValue =
|
|
8043
|
+
this.controlValue = false;
|
|
8044
|
+
this.jsf.updateValue(this, this.falseValue);
|
|
7881
8045
|
}
|
|
7882
8046
|
}
|
|
7883
8047
|
updateValue(event) {
|
|
@@ -7907,7 +8071,7 @@ class CheckboxComponent {
|
|
|
7907
8071
|
type="checkbox">
|
|
7908
8072
|
<input *ngIf="!boundControl"
|
|
7909
8073
|
[attr.aria-describedby]="'control' + layoutNode()?._id + 'Status'"
|
|
7910
|
-
[checked]="isChecked
|
|
8074
|
+
[checked]="isChecked"
|
|
7911
8075
|
[class]="(options?.fieldHtmlClass || '') + (isChecked ?
|
|
7912
8076
|
(' ' + (options?.activeClass || '') + ' ' + (options?.style?.selected || '')) :
|
|
7913
8077
|
(' ' + (options?.style?.unselected || '')))"
|
|
@@ -7944,7 +8108,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
7944
8108
|
type="checkbox">
|
|
7945
8109
|
<input *ngIf="!boundControl"
|
|
7946
8110
|
[attr.aria-describedby]="'control' + layoutNode()?._id + 'Status'"
|
|
7947
|
-
[checked]="isChecked
|
|
8111
|
+
[checked]="isChecked"
|
|
7948
8112
|
[class]="(options?.fieldHtmlClass || '') + (isChecked ?
|
|
7949
8113
|
(' ' + (options?.activeClass || '') + ' ' + (options?.style?.selected || '')) :
|
|
7950
8114
|
(' ' + (options?.style?.unselected || '')))"
|
|
@@ -8741,14 +8905,30 @@ class OneOfComponent {
|
|
|
8741
8905
|
let parts = controlName.split('$');
|
|
8742
8906
|
let fieldName = parts[parts.length - 1];
|
|
8743
8907
|
let controlValue = this.jsf.formGroup.controls[controlName].value;
|
|
8744
|
-
|
|
8745
|
-
|
|
8746
|
-
|
|
8747
|
-
|
|
8748
|
-
|
|
8908
|
+
let controlSchema = JsonPointer.get(this.jsf.schema, parts.join("/"));
|
|
8909
|
+
let schemaPointer = parts.join("/");
|
|
8910
|
+
let dPointer = schemaPointer.replace(/(anyOf|allOf|oneOf|none)\/[\d]+\//g, '')
|
|
8911
|
+
.replace(/(if|then|else|properties)\//g, '');
|
|
8912
|
+
//JsonPointer.toDataPointer(parts.join("/"),this.jsf.schema);
|
|
8913
|
+
let dVal = JsonPointer.get(this.jsf.formValues, dPointer);
|
|
8914
|
+
let compareVal = dVal; //formValue;
|
|
8915
|
+
//compare only values that are in the subschema properties
|
|
8916
|
+
if (controlSchema && controlSchema.properties) {
|
|
8917
|
+
compareVal = isObject$1(dVal) && hasOwn(dVal, fieldName) ?
|
|
8918
|
+
pick(dVal[fieldName], Object.keys(controlSchema.properties))
|
|
8919
|
+
: pick(dVal, Object.keys(controlSchema.properties));
|
|
8920
|
+
}
|
|
8921
|
+
/*
|
|
8922
|
+
if(isObject(compareVal) && hasOwn(compareVal,fieldName) &&
|
|
8923
|
+
isEqual(compareVal[fieldName],controlValue)
|
|
8924
|
+
){
|
|
8925
|
+
foundInd=ind;
|
|
8926
|
+
}else //if(formValue || controlValue){
|
|
8927
|
+
if(isEqual(compareVal,controlValue)){
|
|
8928
|
+
foundInd=ind;
|
|
8749
8929
|
}
|
|
8750
|
-
|
|
8751
|
-
|
|
8930
|
+
*/
|
|
8931
|
+
if (isEqual$2(compareVal, controlValue)) {
|
|
8752
8932
|
foundInd = ind;
|
|
8753
8933
|
}
|
|
8754
8934
|
});
|
|
@@ -9101,6 +9281,63 @@ class RootComponent {
|
|
|
9101
9281
|
}
|
|
9102
9282
|
sortableInit(sortable) {
|
|
9103
9283
|
this.sortableObj = sortable;
|
|
9284
|
+
///NB issue caused by sortablejs when it its destroyed
|
|
9285
|
+
//this mainly affects checkboxes coupled with conditions
|
|
9286
|
+
//-the value is rechecked
|
|
9287
|
+
//-see https://github.com/SortableJS/Sortable/issues/1052#issuecomment-369613072
|
|
9288
|
+
/* attempt to monkey patch sortable js
|
|
9289
|
+
const originalMethod = sortable._nulling;
|
|
9290
|
+
let zone=this.zone;
|
|
9291
|
+
sortable._nulling=function() {
|
|
9292
|
+
console.log(`pluginEvent 2 ${pluginEvent}`)
|
|
9293
|
+
zone.runOutsideAngular(() => {
|
|
9294
|
+
console.log(`pluginEvent3 ${pluginEvent}`)
|
|
9295
|
+
pluginEvent('nulling', this);
|
|
9296
|
+
|
|
9297
|
+
rootEl =
|
|
9298
|
+
dragEl =
|
|
9299
|
+
parentEl =
|
|
9300
|
+
ghostEl =
|
|
9301
|
+
nextEl =
|
|
9302
|
+
cloneEl =
|
|
9303
|
+
lastDownEl =
|
|
9304
|
+
cloneHidden =
|
|
9305
|
+
|
|
9306
|
+
tapEvt =
|
|
9307
|
+
touchEvt =
|
|
9308
|
+
|
|
9309
|
+
moved =
|
|
9310
|
+
newIndex =
|
|
9311
|
+
newDraggableIndex =
|
|
9312
|
+
oldIndex =
|
|
9313
|
+
oldDraggableIndex =
|
|
9314
|
+
|
|
9315
|
+
lastTarget =
|
|
9316
|
+
lastDirection =
|
|
9317
|
+
|
|
9318
|
+
putSortable =
|
|
9319
|
+
activeGroup =
|
|
9320
|
+
Sortable.dragged =
|
|
9321
|
+
Sortable.ghost =
|
|
9322
|
+
Sortable.clone =
|
|
9323
|
+
Sortable.active = null;
|
|
9324
|
+
|
|
9325
|
+
|
|
9326
|
+
let el = this.el;
|
|
9327
|
+
savedInputChecked.forEach(function (checkEl) {
|
|
9328
|
+
if (el.contains(checkEl)) {
|
|
9329
|
+
checkEl.checked = true;
|
|
9330
|
+
}
|
|
9331
|
+
});
|
|
9332
|
+
|
|
9333
|
+
savedInputChecked.length =
|
|
9334
|
+
lastDx =
|
|
9335
|
+
lastDy = 0;
|
|
9336
|
+
|
|
9337
|
+
})
|
|
9338
|
+
|
|
9339
|
+
}.bind(sortable)
|
|
9340
|
+
*/
|
|
9104
9341
|
}
|
|
9105
9342
|
isDraggable(node) {
|
|
9106
9343
|
let result = node.arrayItem && node.type !== '$ref' &&
|
|
@@ -10670,7 +10907,9 @@ class JsonSchemaFormComponent {
|
|
|
10670
10907
|
*/
|
|
10671
10908
|
initializeAjv() {
|
|
10672
10909
|
const form = this.form();
|
|
10673
|
-
const ajvOptions = cloneDeep(this.ajvOptions()) ||
|
|
10910
|
+
const ajvOptions = cloneDeep(this.ajvOptions()) ||
|
|
10911
|
+
(form && hasOwn(form, 'ajvOptions') && isObject(form.ajvOptions)
|
|
10912
|
+
&& cloneDeep(form.ajvOptions));
|
|
10674
10913
|
if (ajvOptions) {
|
|
10675
10914
|
this.ajvInstanceName = this.jsf.createAndRegisterAjvInstance(ajvOptions).name;
|
|
10676
10915
|
}
|