@ng-formworks/core 16.6.0 → 16.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/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, isObject as isObject$1, pick, 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
|
}
|
|
@@ -7312,7 +7451,8 @@ class JsonSchemaFormService {
|
|
|
7312
7451
|
ctx.formControl = this.getFormControl(ctx);
|
|
7313
7452
|
//introduced to check if the node is part of ITE conditional
|
|
7314
7453
|
//then change or add the control
|
|
7315
|
-
if (layoutNode?.schemaPointer
|
|
7454
|
+
if (layoutNode?.schemaPointer && layoutNode.isITEItem ||
|
|
7455
|
+
(layoutNode?.schemaPointer && layoutNode?.oneOfPointer)) {
|
|
7316
7456
|
//before changing control, need to set the new data type for data formatting
|
|
7317
7457
|
const schemaType = this.dataMap.get(layoutNode?.dataPointer).get("schemaType");
|
|
7318
7458
|
if (schemaType != layoutNode.dataType) {
|
|
@@ -7353,11 +7493,24 @@ class JsonSchemaFormService {
|
|
|
7353
7493
|
}
|
|
7354
7494
|
//if this is a ITE conditional field, the value would not have been
|
|
7355
7495
|
//set, as the control would only be initialized when the condition is true
|
|
7356
|
-
|
|
7357
|
-
|
|
7358
|
-
|
|
7359
|
-
|
|
7360
|
-
ctx.formControl
|
|
7496
|
+
//TODO-review need to decide which of the data sets between data,formValues and default
|
|
7497
|
+
//to use for the value
|
|
7498
|
+
if (ctx.options?.condition || layoutNode?.oneOfPointer) {
|
|
7499
|
+
const dataPointer = this.getDataPointer(ctx);
|
|
7500
|
+
const controlValue = ctx.formControl.value;
|
|
7501
|
+
const dataValue = JsonPointer.has(this.data, dataPointer) ?
|
|
7502
|
+
JsonPointer.get(this.data, dataPointer) : undefined;
|
|
7503
|
+
const formValue = JsonPointer.has(this.formValues, dataPointer) ?
|
|
7504
|
+
JsonPointer.get(this.formValues, dataPointer) : undefined;
|
|
7505
|
+
const schemaDefault = ctx.options?.default;
|
|
7506
|
+
//if initial formValues was supplied and controlValue matches formValue then likely
|
|
7507
|
+
//control was initially created with the formValue then set value to data value
|
|
7508
|
+
//if no formValues was supplied and controlValue matches schemaDefault then likely
|
|
7509
|
+
//control was initially created with the default then set value to data value
|
|
7510
|
+
const value = this.formValues && isEqual$1(formValue, controlValue) ? dataValue
|
|
7511
|
+
: !this.formValues && isEqual$1(schemaDefault, controlValue) ? dataValue
|
|
7512
|
+
: schemaDefault;
|
|
7513
|
+
ctx.formControl?.patchValue(value);
|
|
7361
7514
|
}
|
|
7362
7515
|
return ctx.boundControl;
|
|
7363
7516
|
}
|
|
@@ -7473,7 +7626,9 @@ class JsonSchemaFormService {
|
|
|
7473
7626
|
ctx.layoutNode.type === '$ref') {
|
|
7474
7627
|
return null;
|
|
7475
7628
|
}
|
|
7476
|
-
|
|
7629
|
+
const schemaPointer = ctx.layoutNode?.isITEItem ? ctx.layoutNode?.schemaPointer : null;
|
|
7630
|
+
const oneOfPointer = ctx.layoutNode?.oneOfPointer;
|
|
7631
|
+
return getControl(this.formGroup, this.getDataPointer(ctx), false, schemaPointer || oneOfPointer);
|
|
7477
7632
|
}
|
|
7478
7633
|
setFormControl(ctx, control) {
|
|
7479
7634
|
if (!ctx || !ctx.layoutNode ||
|
|
@@ -7489,14 +7644,18 @@ class JsonSchemaFormService {
|
|
|
7489
7644
|
ctx.layoutNode.type === '$ref') {
|
|
7490
7645
|
return null;
|
|
7491
7646
|
}
|
|
7492
|
-
const
|
|
7647
|
+
const schemaPointer = ctx.layoutNode?.isITEItem ? ctx.layoutNode?.schemaPointer : null;
|
|
7648
|
+
const oneOfPointer = ctx.layoutNode?.oneOfPointer;
|
|
7649
|
+
const control = getControl(this.formGroup, this.getDataPointer(ctx), false, schemaPointer || oneOfPointer);
|
|
7493
7650
|
return control ? control.value : null;
|
|
7494
7651
|
}
|
|
7495
7652
|
getFormControlGroup(ctx) {
|
|
7496
7653
|
if (!ctx.layoutNode || !isDefined(ctx.layoutNode.dataPointer)) {
|
|
7497
7654
|
return null;
|
|
7498
7655
|
}
|
|
7499
|
-
|
|
7656
|
+
const schemaPointer = ctx.layoutNode?.isITEItem ? ctx.layoutNode?.schemaPointer : null;
|
|
7657
|
+
const oneOfPointer = ctx.layoutNode?.oneOfPointer;
|
|
7658
|
+
return getControl(this.formGroup, this.getDataPointer(ctx), true, schemaPointer || oneOfPointer);
|
|
7500
7659
|
}
|
|
7501
7660
|
getFormControlName(ctx) {
|
|
7502
7661
|
if (!ctx.layoutNode ||
|
|
@@ -7858,6 +8017,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
7858
8017
|
type: Input
|
|
7859
8018
|
}] } });
|
|
7860
8019
|
|
|
8020
|
+
///NB issue caused by sortablejs when it its destroyed
|
|
8021
|
+
//this mainly affects checkboxes coupled with conditions
|
|
8022
|
+
//-the value is rechecked
|
|
8023
|
+
//-see https://github.com/SortableJS/Sortable/issues/1052#issuecomment-369613072
|
|
7861
8024
|
class CheckboxComponent {
|
|
7862
8025
|
constructor(jsf) {
|
|
7863
8026
|
this.jsf = jsf;
|
|
@@ -7870,7 +8033,8 @@ class CheckboxComponent {
|
|
|
7870
8033
|
this.options = this.layoutNode.options || {};
|
|
7871
8034
|
this.jsf.initializeControl(this);
|
|
7872
8035
|
if (this.controlValue === null || this.controlValue === undefined) {
|
|
7873
|
-
this.controlValue =
|
|
8036
|
+
this.controlValue = false;
|
|
8037
|
+
this.jsf.updateValue(this, this.falseValue);
|
|
7874
8038
|
}
|
|
7875
8039
|
}
|
|
7876
8040
|
updateValue(event) {
|
|
@@ -7900,7 +8064,7 @@ class CheckboxComponent {
|
|
|
7900
8064
|
type="checkbox">
|
|
7901
8065
|
<input *ngIf="!boundControl"
|
|
7902
8066
|
[attr.aria-describedby]="'control' + layoutNode?._id + 'Status'"
|
|
7903
|
-
[checked]="isChecked
|
|
8067
|
+
[checked]="isChecked"
|
|
7904
8068
|
[class]="(options?.fieldHtmlClass || '') + (isChecked ?
|
|
7905
8069
|
(' ' + (options?.activeClass || '') + ' ' + (options?.style?.selected || '')) :
|
|
7906
8070
|
(' ' + (options?.style?.unselected || '')))"
|
|
@@ -7937,7 +8101,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
7937
8101
|
type="checkbox">
|
|
7938
8102
|
<input *ngIf="!boundControl"
|
|
7939
8103
|
[attr.aria-describedby]="'control' + layoutNode?._id + 'Status'"
|
|
7940
|
-
[checked]="isChecked
|
|
8104
|
+
[checked]="isChecked"
|
|
7941
8105
|
[class]="(options?.fieldHtmlClass || '') + (isChecked ?
|
|
7942
8106
|
(' ' + (options?.activeClass || '') + ' ' + (options?.style?.selected || '')) :
|
|
7943
8107
|
(' ' + (options?.style?.unselected || '')))"
|
|
@@ -8759,14 +8923,30 @@ class OneOfComponent {
|
|
|
8759
8923
|
let parts = controlName.split('$');
|
|
8760
8924
|
let fieldName = parts[parts.length - 1];
|
|
8761
8925
|
let controlValue = this.jsf.formGroup.controls[controlName].value;
|
|
8762
|
-
|
|
8763
|
-
|
|
8764
|
-
|
|
8765
|
-
|
|
8766
|
-
|
|
8926
|
+
let controlSchema = JsonPointer.get(this.jsf.schema, parts.join("/"));
|
|
8927
|
+
let schemaPointer = parts.join("/");
|
|
8928
|
+
let dPointer = schemaPointer.replace(/(anyOf|allOf|oneOf|none)\/[\d]+\//g, '')
|
|
8929
|
+
.replace(/(if|then|else|properties)\//g, '');
|
|
8930
|
+
//JsonPointer.toDataPointer(parts.join("/"),this.jsf.schema);
|
|
8931
|
+
let dVal = JsonPointer.get(this.jsf.formValues, dPointer);
|
|
8932
|
+
let compareVal = dVal; //formValue;
|
|
8933
|
+
//compare only values that are in the subschema properties
|
|
8934
|
+
if (controlSchema && controlSchema.properties) {
|
|
8935
|
+
compareVal = isObject$1(dVal) && hasOwn(dVal, fieldName) ?
|
|
8936
|
+
pick(dVal[fieldName], Object.keys(controlSchema.properties))
|
|
8937
|
+
: pick(dVal, Object.keys(controlSchema.properties));
|
|
8938
|
+
}
|
|
8939
|
+
/*
|
|
8940
|
+
if(isObject(compareVal) && hasOwn(compareVal,fieldName) &&
|
|
8941
|
+
isEqual(compareVal[fieldName],controlValue)
|
|
8942
|
+
){
|
|
8943
|
+
foundInd=ind;
|
|
8944
|
+
}else //if(formValue || controlValue){
|
|
8945
|
+
if(isEqual(compareVal,controlValue)){
|
|
8946
|
+
foundInd=ind;
|
|
8767
8947
|
}
|
|
8768
|
-
|
|
8769
|
-
|
|
8948
|
+
*/
|
|
8949
|
+
if (isEqual$2(compareVal, controlValue)) {
|
|
8770
8950
|
foundInd = ind;
|
|
8771
8951
|
}
|
|
8772
8952
|
});
|
|
@@ -9124,6 +9304,63 @@ class RootComponent {
|
|
|
9124
9304
|
}
|
|
9125
9305
|
sortableInit(sortable) {
|
|
9126
9306
|
this.sortableObj = sortable;
|
|
9307
|
+
///NB issue caused by sortablejs when it its destroyed
|
|
9308
|
+
//this mainly affects checkboxes coupled with conditions
|
|
9309
|
+
//-the value is rechecked
|
|
9310
|
+
//-see https://github.com/SortableJS/Sortable/issues/1052#issuecomment-369613072
|
|
9311
|
+
/* attempt to monkey patch sortable js
|
|
9312
|
+
const originalMethod = sortable._nulling;
|
|
9313
|
+
let zone=this.zone;
|
|
9314
|
+
sortable._nulling=function() {
|
|
9315
|
+
console.log(`pluginEvent 2 ${pluginEvent}`)
|
|
9316
|
+
zone.runOutsideAngular(() => {
|
|
9317
|
+
console.log(`pluginEvent3 ${pluginEvent}`)
|
|
9318
|
+
pluginEvent('nulling', this);
|
|
9319
|
+
|
|
9320
|
+
rootEl =
|
|
9321
|
+
dragEl =
|
|
9322
|
+
parentEl =
|
|
9323
|
+
ghostEl =
|
|
9324
|
+
nextEl =
|
|
9325
|
+
cloneEl =
|
|
9326
|
+
lastDownEl =
|
|
9327
|
+
cloneHidden =
|
|
9328
|
+
|
|
9329
|
+
tapEvt =
|
|
9330
|
+
touchEvt =
|
|
9331
|
+
|
|
9332
|
+
moved =
|
|
9333
|
+
newIndex =
|
|
9334
|
+
newDraggableIndex =
|
|
9335
|
+
oldIndex =
|
|
9336
|
+
oldDraggableIndex =
|
|
9337
|
+
|
|
9338
|
+
lastTarget =
|
|
9339
|
+
lastDirection =
|
|
9340
|
+
|
|
9341
|
+
putSortable =
|
|
9342
|
+
activeGroup =
|
|
9343
|
+
Sortable.dragged =
|
|
9344
|
+
Sortable.ghost =
|
|
9345
|
+
Sortable.clone =
|
|
9346
|
+
Sortable.active = null;
|
|
9347
|
+
|
|
9348
|
+
|
|
9349
|
+
let el = this.el;
|
|
9350
|
+
savedInputChecked.forEach(function (checkEl) {
|
|
9351
|
+
if (el.contains(checkEl)) {
|
|
9352
|
+
checkEl.checked = true;
|
|
9353
|
+
}
|
|
9354
|
+
});
|
|
9355
|
+
|
|
9356
|
+
savedInputChecked.length =
|
|
9357
|
+
lastDx =
|
|
9358
|
+
lastDy = 0;
|
|
9359
|
+
|
|
9360
|
+
})
|
|
9361
|
+
|
|
9362
|
+
}.bind(sortable)
|
|
9363
|
+
*/
|
|
9127
9364
|
}
|
|
9128
9365
|
isDraggable(node) {
|
|
9129
9366
|
let result = node.arrayItem && node.type !== '$ref' &&
|
|
@@ -10692,7 +10929,9 @@ class JsonSchemaFormComponent {
|
|
|
10692
10929
|
*/
|
|
10693
10930
|
initializeAjv() {
|
|
10694
10931
|
const form = this.form;
|
|
10695
|
-
const ajvOptions = cloneDeep(this.ajvOptions) ||
|
|
10932
|
+
const ajvOptions = cloneDeep(this.ajvOptions) ||
|
|
10933
|
+
(form && hasOwn(form, 'ajvOptions') && isObject(form.ajvOptions)
|
|
10934
|
+
&& cloneDeep(form.ajvOptions));
|
|
10696
10935
|
if (ajvOptions) {
|
|
10697
10936
|
this.ajvInstanceName = this.jsf.createAndRegisterAjvInstance(ajvOptions).name;
|
|
10698
10937
|
}
|