@ng-formworks/core 19.6.0 → 19.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.
|
@@ -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);
|
|
@@ -6200,6 +6292,37 @@ function fixNestedArrayLayout(options) {
|
|
|
6200
6292
|
* //
|
|
6201
6293
|
*/
|
|
6202
6294
|
function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPointer = '', dataPointer = '', arrayItem = false, arrayItemType = null, removable = null, forRefLibrary = false, dataPointerPrefix = '', jsonSchema) {
|
|
6295
|
+
function applyITEConditions(builtLayout, schPointer, keySchemaPointer, negateClause, parentLayout) {
|
|
6296
|
+
if (builtLayout) {
|
|
6297
|
+
if (parentLayout && parentLayout.isITEItem && parentLayout.options.condition) {
|
|
6298
|
+
return;
|
|
6299
|
+
}
|
|
6300
|
+
if (isArray(builtLayout)) {
|
|
6301
|
+
builtLayout.forEach(item => {
|
|
6302
|
+
item.isITEItem = true;
|
|
6303
|
+
item.options.condition = convertJSONSchemaIfToCondition(schema, item, negateClause);
|
|
6304
|
+
applyITEConditions(item, schPointer, keySchemaPointer, negateClause, builtLayout);
|
|
6305
|
+
//item.schemaPointer = schPointer + keySchemaPointer + item.dataPointer;
|
|
6306
|
+
//item.options.condition = convertJSONSchemaIfToCondition(schema, negateClause);
|
|
6307
|
+
//newSection.push(item);
|
|
6308
|
+
});
|
|
6309
|
+
}
|
|
6310
|
+
else if (hasOwn(builtLayout, "items")) {
|
|
6311
|
+
applyITEConditions(builtLayout.items, schPointer, keySchemaPointer, negateClause, builtLayout);
|
|
6312
|
+
// builtLayout.items.forEach(item => {
|
|
6313
|
+
// item.isITEItem=true;
|
|
6314
|
+
// item.options.condition = convertJSONSchemaIfToCondition(schema,item, negateClause);
|
|
6315
|
+
// applyITEConditions(item,schPointer,keySchemaPointer,negateClause)
|
|
6316
|
+
// });
|
|
6317
|
+
}
|
|
6318
|
+
else {
|
|
6319
|
+
builtLayout.isITEItem = true;
|
|
6320
|
+
//builtLayout.schemaPointer = `${schPointer}${keySchemaPointer}/${builtLayout.name}`;
|
|
6321
|
+
builtLayout.options.condition = convertJSONSchemaIfToCondition(schema, builtLayout, negateClause);
|
|
6322
|
+
//newSection.push(builtLayout)
|
|
6323
|
+
}
|
|
6324
|
+
}
|
|
6325
|
+
}
|
|
6203
6326
|
const jsSchema = jsonSchema || jsf.schema;
|
|
6204
6327
|
const schema = JsonPointer.get(jsSchema, schemaPointer);
|
|
6205
6328
|
//JsonPointer.get(jsf.schema, schemaPointer);
|
|
@@ -6237,6 +6360,7 @@ function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPoint
|
|
|
6237
6360
|
if (!jsf.dataMap.has(shortDataPointer)) {
|
|
6238
6361
|
jsf.dataMap.set(shortDataPointer, new Map());
|
|
6239
6362
|
}
|
|
6363
|
+
updateInputOptions(newNode, schema, jsf);
|
|
6240
6364
|
const nodeDataMap = jsf.dataMap.get(shortDataPointer);
|
|
6241
6365
|
if (!nodeDataMap.has('inputType')) {
|
|
6242
6366
|
nodeDataMap.set('schemaPointer', schemaPointer);
|
|
@@ -6244,7 +6368,7 @@ function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPoint
|
|
|
6244
6368
|
nodeDataMap.set('widget', newNode.widget);
|
|
6245
6369
|
nodeDataMap.set('disabled', !!newNode.options.disabled);
|
|
6246
6370
|
}
|
|
6247
|
-
updateInputOptions(newNode, schema, jsf);
|
|
6371
|
+
//updateInputOptions(newNode, schema, jsf);
|
|
6248
6372
|
if (!newNode.options.title && newNode.name && !/^\d+$/.test(newNode.name)) {
|
|
6249
6373
|
newNode.options.title = fixTitle(newNode.name);
|
|
6250
6374
|
}
|
|
@@ -6272,6 +6396,7 @@ function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPoint
|
|
|
6272
6396
|
'/properties/' + key : '/additionalProperties';
|
|
6273
6397
|
const innerItem = buildLayoutFromSchema(jsf, widgetLibrary, isObject(nodeValue) ? nodeValue[key] : null, schemaPointer + keySchemaPointer, dataPointer + '/' + key, false, null, null, forRefLibrary, dataPointerPrefix);
|
|
6274
6398
|
if (innerItem) {
|
|
6399
|
+
innerItem.schemaPointer = schemaPointer + keySchemaPointer;
|
|
6275
6400
|
if (isInputRequired(schema, '/' + key)) {
|
|
6276
6401
|
innerItem.options.required = true;
|
|
6277
6402
|
jsf.fieldsRequired = true;
|
|
@@ -6296,38 +6421,50 @@ function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPoint
|
|
|
6296
6421
|
}
|
|
6297
6422
|
schema[ofType].forEach((ofItem, ind) => {
|
|
6298
6423
|
const keySchemaPointer = `/${ofType}/${ind}`;
|
|
6299
|
-
const innerItem = buildLayoutFromSchema(jsf, widgetLibrary, ofItem, schemaPointer + keySchemaPointer, dataPointer, false, null, null, forRefLibrary
|
|
6424
|
+
const innerItem = buildLayoutFromSchema(jsf, widgetLibrary, ofItem, schemaPointer + keySchemaPointer, dataPointer, false, null, null, ofType == "oneOf" /*forRefLibrary*/, dataPointerPrefix);
|
|
6300
6425
|
if (innerItem) {
|
|
6301
6426
|
//newSection.push(innerItem);
|
|
6302
6427
|
if (innerItem.items) {
|
|
6303
6428
|
innerItem.items.forEach(innerItemLevel2 => {
|
|
6304
6429
|
const l2SchemaPointer = hasOwn(ofItem, 'properties') ?
|
|
6305
6430
|
'/properties/' + innerItemLevel2.name : innerItemLevel2.name;
|
|
6306
|
-
innerItemLevel2.oneOfPointer =
|
|
6307
|
-
innerItemLevel2.schemaPointer
|
|
6431
|
+
//innerItemLevel2.oneOfPointer = schemaPointer + keySchemaPointer + l2SchemaPointer;
|
|
6432
|
+
// innerItemLevel2.schemaPointer=innerItemLevel2.schemaPointer;
|
|
6433
|
+
innerItemLevel2.oneOfPointer = innerItemLevel2.schemaPointer;
|
|
6308
6434
|
});
|
|
6309
6435
|
}
|
|
6436
|
+
//TODO review-will never reach here if forRefLibrary==true
|
|
6310
6437
|
if (isArray(innerItem)) {
|
|
6438
|
+
let outerOneOfItemTpl = cloneDeep(newNode);
|
|
6439
|
+
outerOneOfItemTpl;
|
|
6311
6440
|
innerItem.forEach(item => {
|
|
6312
6441
|
const l2SchemaPointer = hasOwn(ofItem, 'properties') ?
|
|
6313
6442
|
'/properties/' + item.name : item.name;
|
|
6314
6443
|
if (outerOneOfItem) {
|
|
6315
|
-
item.oneOfPointer =
|
|
6444
|
+
////item.oneOfPointer = schemaPointer + keySchemaPointer + l2SchemaPointer;
|
|
6316
6445
|
//schemaPointer + keySchemaPointer + item.dataPointer;
|
|
6317
|
-
item.schemaPointer
|
|
6318
|
-
|
|
6446
|
+
////item.schemaPointer=item.oneOfPointer;
|
|
6447
|
+
/*
|
|
6448
|
+
outerOneOfItem.items=outerOneOfItem.items||[];
|
|
6319
6449
|
outerOneOfItem.items.push(item);
|
|
6450
|
+
*/
|
|
6451
|
+
outerOneOfItemTpl.items = outerOneOfItemTpl.items || [];
|
|
6452
|
+
outerOneOfItemTpl.items.push(item);
|
|
6320
6453
|
}
|
|
6321
6454
|
else {
|
|
6322
6455
|
newSection.push(item);
|
|
6323
6456
|
}
|
|
6324
6457
|
});
|
|
6458
|
+
if (outerOneOfItem) {
|
|
6459
|
+
outerOneOfItem.items = outerOneOfItem.items || [];
|
|
6460
|
+
outerOneOfItem.items.push(outerOneOfItemTpl);
|
|
6461
|
+
}
|
|
6325
6462
|
//TODO test-might not work for more than 2 levels of nesting
|
|
6326
6463
|
}
|
|
6327
6464
|
else {
|
|
6328
6465
|
if (outerOneOfItem) {
|
|
6329
6466
|
innerItem.oneOfPointer = schemaPointer + keySchemaPointer; // + innerItem.dataPointer;
|
|
6330
|
-
innerItem.schemaPointer
|
|
6467
|
+
////innerItem.schemaPointer=innerItem.oneOfPointer;
|
|
6331
6468
|
outerOneOfItem.items = outerOneOfItem.items || [];
|
|
6332
6469
|
outerOneOfItem.items.push(innerItem);
|
|
6333
6470
|
}
|
|
@@ -6346,16 +6483,17 @@ function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPoint
|
|
|
6346
6483
|
const negateClause = con == "else";
|
|
6347
6484
|
const innerItem = buildLayoutFromSchema(jsf, widgetLibrary, nodeValue.then, schemaPointer + keySchemaPointer, dataPointer, false, null, null, forRefLibrary, dataPointerPrefix);
|
|
6348
6485
|
if (innerItem) {
|
|
6486
|
+
applyITEConditions(innerItem, schemaPointer, keySchemaPointer, negateClause);
|
|
6349
6487
|
if (isArray(innerItem)) {
|
|
6350
6488
|
innerItem.forEach(item => {
|
|
6351
|
-
item.schemaPointer = schemaPointer + keySchemaPointer + item.dataPointer;
|
|
6352
|
-
item.options.condition = convertJSONSchemaIfToCondition(schema, negateClause);
|
|
6489
|
+
//item.schemaPointer = schemaPointer + keySchemaPointer + item.dataPointer;
|
|
6490
|
+
//item.options.condition = convertJSONSchemaIfToCondition(schema, negateClause);
|
|
6353
6491
|
newSection.push(item);
|
|
6354
6492
|
});
|
|
6355
6493
|
}
|
|
6356
6494
|
else {
|
|
6357
|
-
innerItem.schemaPointer = schemaPointer + keySchemaPointer + innerItem.dataPointer;
|
|
6358
|
-
innerItem.options.condition = convertJSONSchemaIfToCondition(schema, negateClause);
|
|
6495
|
+
//innerItem.schemaPointer = schemaPointer + keySchemaPointer + innerItem.dataPointer;
|
|
6496
|
+
//innerItem.options.condition = convertJSONSchemaIfToCondition(schema, negateClause);
|
|
6359
6497
|
newSection.push(innerItem);
|
|
6360
6498
|
}
|
|
6361
6499
|
}
|
|
@@ -6572,17 +6710,18 @@ function buildLayoutFromSchema(jsf, widgetLibrary, nodeValue = null, schemaPoint
|
|
|
6572
6710
|
const negateClause = con == "else";
|
|
6573
6711
|
const innerItem = buildLayoutFromSchema(jsf, widgetLibrary, nodeValue.then, schemaPointer + keySchemaPointer, dataPointer, false, null, null, forRefLibrary, dataPointerPrefix);
|
|
6574
6712
|
if (innerItem) {
|
|
6713
|
+
applyITEConditions(innerItem, schemaPointer, keySchemaPointer, negateClause);
|
|
6575
6714
|
if (isArray(innerItem)) {
|
|
6576
6715
|
innerItem.forEach(item => {
|
|
6577
|
-
item.schemaPointer = schemaPointer + keySchemaPointer + item.dataPointer;
|
|
6578
|
-
item.options.condition = convertJSONSchemaIfToCondition(schema, negateClause);
|
|
6716
|
+
//item.schemaPointer = schemaPointer + keySchemaPointer + item.dataPointer;
|
|
6717
|
+
//item.options.condition = convertJSONSchemaIfToCondition(schema, negateClause);
|
|
6579
6718
|
newSection.push(item);
|
|
6580
6719
|
newNode = newSection;
|
|
6581
6720
|
});
|
|
6582
6721
|
}
|
|
6583
6722
|
else {
|
|
6584
|
-
innerItem.schemaPointer = schemaPointer + keySchemaPointer + innerItem.dataPointer;
|
|
6585
|
-
innerItem.options.condition = convertJSONSchemaIfToCondition(schema, negateClause);
|
|
6723
|
+
//innerItem.schemaPointer = schemaPointer + keySchemaPointer + innerItem.dataPointer;
|
|
6724
|
+
//innerItem.options.condition = convertJSONSchemaIfToCondition(schema, negateClause);
|
|
6586
6725
|
newNode = innerItem;
|
|
6587
6726
|
}
|
|
6588
6727
|
}
|
|
@@ -7331,7 +7470,8 @@ class JsonSchemaFormService {
|
|
|
7331
7470
|
ctx.formControl = this.getFormControl(ctx);
|
|
7332
7471
|
//introduced to check if the node is part of ITE conditional
|
|
7333
7472
|
//then change or add the control
|
|
7334
|
-
if (layoutNode?.schemaPointer
|
|
7473
|
+
if (layoutNode?.schemaPointer && layoutNode.isITEItem ||
|
|
7474
|
+
(layoutNode?.schemaPointer && layoutNode?.oneOfPointer)) {
|
|
7335
7475
|
//before changing control, need to set the new data type for data formatting
|
|
7336
7476
|
const schemaType = this.dataMap.get(layoutNode?.dataPointer).get("schemaType");
|
|
7337
7477
|
if (schemaType != layoutNode.dataType) {
|
|
@@ -7372,11 +7512,24 @@ class JsonSchemaFormService {
|
|
|
7372
7512
|
}
|
|
7373
7513
|
//if this is a ITE conditional field, the value would not have been
|
|
7374
7514
|
//set, as the control would only be initialized when the condition is true
|
|
7375
|
-
|
|
7376
|
-
|
|
7377
|
-
|
|
7378
|
-
|
|
7379
|
-
ctx.formControl
|
|
7515
|
+
//TODO-review need to decide which of the data sets between data,formValues and default
|
|
7516
|
+
//to use for the value
|
|
7517
|
+
if (ctx.options?.condition || layoutNode?.oneOfPointer) {
|
|
7518
|
+
const dataPointer = this.getDataPointer(ctx);
|
|
7519
|
+
const controlValue = ctx.formControl.value;
|
|
7520
|
+
const dataValue = JsonPointer.has(this.data, dataPointer) ?
|
|
7521
|
+
JsonPointer.get(this.data, dataPointer) : undefined;
|
|
7522
|
+
const formValue = JsonPointer.has(this.formValues, dataPointer) ?
|
|
7523
|
+
JsonPointer.get(this.formValues, dataPointer) : undefined;
|
|
7524
|
+
const schemaDefault = ctx.options?.default;
|
|
7525
|
+
//if initial formValues was supplied and controlValue matches formValue then likely
|
|
7526
|
+
//control was initially created with the formValue then set value to data value
|
|
7527
|
+
//if no formValues was supplied and controlValue matches schemaDefault then likely
|
|
7528
|
+
//control was initially created with the default then set value to data value
|
|
7529
|
+
const value = this.formValues && isEqual$1(formValue, controlValue) ? dataValue
|
|
7530
|
+
: !this.formValues && isEqual$1(schemaDefault, controlValue) ? dataValue
|
|
7531
|
+
: schemaDefault;
|
|
7532
|
+
ctx.formControl?.patchValue(value);
|
|
7380
7533
|
}
|
|
7381
7534
|
return ctx.boundControl;
|
|
7382
7535
|
}
|
|
@@ -7492,7 +7645,9 @@ class JsonSchemaFormService {
|
|
|
7492
7645
|
ctx.layoutNode().type === '$ref') {
|
|
7493
7646
|
return null;
|
|
7494
7647
|
}
|
|
7495
|
-
|
|
7648
|
+
const schemaPointer = ctx.layoutNode()?.isITEItem ? ctx.layoutNode()?.schemaPointer : null;
|
|
7649
|
+
const oneOfPointer = ctx.layoutNode()?.oneOfPointer;
|
|
7650
|
+
return getControl(this.formGroup, this.getDataPointer(ctx), false, schemaPointer || oneOfPointer);
|
|
7496
7651
|
}
|
|
7497
7652
|
setFormControl(ctx, control) {
|
|
7498
7653
|
if (!ctx || !ctx.layoutNode ||
|
|
@@ -7508,14 +7663,18 @@ class JsonSchemaFormService {
|
|
|
7508
7663
|
ctx.layoutNode().type === '$ref') {
|
|
7509
7664
|
return null;
|
|
7510
7665
|
}
|
|
7511
|
-
const
|
|
7666
|
+
const schemaPointer = ctx.layoutNode()?.isITEItem ? ctx.layoutNode()?.schemaPointer : null;
|
|
7667
|
+
const oneOfPointer = ctx.layoutNode()?.oneOfPointer;
|
|
7668
|
+
const control = getControl(this.formGroup, this.getDataPointer(ctx), false, schemaPointer || oneOfPointer);
|
|
7512
7669
|
return control ? control.value : null;
|
|
7513
7670
|
}
|
|
7514
7671
|
getFormControlGroup(ctx) {
|
|
7515
7672
|
if (!ctx || !ctx.layoutNode || !isDefined(ctx.layoutNode().dataPointer)) {
|
|
7516
7673
|
return null;
|
|
7517
7674
|
}
|
|
7518
|
-
|
|
7675
|
+
const schemaPointer = ctx.layoutNode()?.isITEItem ? ctx.layoutNode()?.schemaPointer : null;
|
|
7676
|
+
const oneOfPointer = ctx.layoutNode()?.oneOfPointer;
|
|
7677
|
+
return getControl(this.formGroup, this.getDataPointer(ctx), true, schemaPointer || oneOfPointer);
|
|
7519
7678
|
}
|
|
7520
7679
|
getFormControlName(ctx) {
|
|
7521
7680
|
if (!ctx || !ctx.layoutNode ||
|
|
@@ -7868,6 +8027,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
7868
8027
|
}]
|
|
7869
8028
|
}] });
|
|
7870
8029
|
|
|
8030
|
+
///NB issue caused by sortablejs when it its destroyed
|
|
8031
|
+
//this mainly affects checkboxes coupled with conditions
|
|
8032
|
+
//-the value is rechecked
|
|
8033
|
+
//-see https://github.com/SortableJS/Sortable/issues/1052#issuecomment-369613072
|
|
7871
8034
|
class CheckboxComponent {
|
|
7872
8035
|
constructor() {
|
|
7873
8036
|
this.jsf = inject(JsonSchemaFormService);
|
|
@@ -7883,7 +8046,8 @@ class CheckboxComponent {
|
|
|
7883
8046
|
this.options = this.layoutNode().options || {};
|
|
7884
8047
|
this.jsf.initializeControl(this);
|
|
7885
8048
|
if (this.controlValue === null || this.controlValue === undefined) {
|
|
7886
|
-
this.controlValue =
|
|
8049
|
+
this.controlValue = false;
|
|
8050
|
+
this.jsf.updateValue(this, this.falseValue);
|
|
7887
8051
|
}
|
|
7888
8052
|
}
|
|
7889
8053
|
updateValue(event) {
|
|
@@ -7913,7 +8077,7 @@ class CheckboxComponent {
|
|
|
7913
8077
|
type="checkbox">
|
|
7914
8078
|
<input *ngIf="!boundControl"
|
|
7915
8079
|
[attr.aria-describedby]="'control' + layoutNode()?._id + 'Status'"
|
|
7916
|
-
[checked]="isChecked
|
|
8080
|
+
[checked]="isChecked"
|
|
7917
8081
|
[class]="(options?.fieldHtmlClass || '') + (isChecked ?
|
|
7918
8082
|
(' ' + (options?.activeClass || '') + ' ' + (options?.style?.selected || '')) :
|
|
7919
8083
|
(' ' + (options?.style?.unselected || '')))"
|
|
@@ -7950,7 +8114,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
7950
8114
|
type="checkbox">
|
|
7951
8115
|
<input *ngIf="!boundControl"
|
|
7952
8116
|
[attr.aria-describedby]="'control' + layoutNode()?._id + 'Status'"
|
|
7953
|
-
[checked]="isChecked
|
|
8117
|
+
[checked]="isChecked"
|
|
7954
8118
|
[class]="(options?.fieldHtmlClass || '') + (isChecked ?
|
|
7955
8119
|
(' ' + (options?.activeClass || '') + ' ' + (options?.style?.selected || '')) :
|
|
7956
8120
|
(' ' + (options?.style?.unselected || '')))"
|
|
@@ -8756,14 +8920,30 @@ class OneOfComponent {
|
|
|
8756
8920
|
let parts = controlName.split('$');
|
|
8757
8921
|
let fieldName = parts[parts.length - 1];
|
|
8758
8922
|
let controlValue = this.jsf.formGroup.controls[controlName].value;
|
|
8759
|
-
|
|
8760
|
-
|
|
8761
|
-
|
|
8762
|
-
|
|
8763
|
-
|
|
8923
|
+
let controlSchema = JsonPointer.get(this.jsf.schema, parts.join("/"));
|
|
8924
|
+
let schemaPointer = parts.join("/");
|
|
8925
|
+
let dPointer = schemaPointer.replace(/(anyOf|allOf|oneOf|none)\/[\d]+\//g, '')
|
|
8926
|
+
.replace(/(if|then|else|properties)\//g, '');
|
|
8927
|
+
//JsonPointer.toDataPointer(parts.join("/"),this.jsf.schema);
|
|
8928
|
+
let dVal = JsonPointer.get(this.jsf.formValues, dPointer);
|
|
8929
|
+
let compareVal = dVal; //formValue;
|
|
8930
|
+
//compare only values that are in the subschema properties
|
|
8931
|
+
if (controlSchema && controlSchema.properties) {
|
|
8932
|
+
compareVal = isObject$1(dVal) && hasOwn(dVal, fieldName) ?
|
|
8933
|
+
pick(dVal[fieldName], Object.keys(controlSchema.properties))
|
|
8934
|
+
: pick(dVal, Object.keys(controlSchema.properties));
|
|
8935
|
+
}
|
|
8936
|
+
/*
|
|
8937
|
+
if(isObject(compareVal) && hasOwn(compareVal,fieldName) &&
|
|
8938
|
+
isEqual(compareVal[fieldName],controlValue)
|
|
8939
|
+
){
|
|
8940
|
+
foundInd=ind;
|
|
8941
|
+
}else //if(formValue || controlValue){
|
|
8942
|
+
if(isEqual(compareVal,controlValue)){
|
|
8943
|
+
foundInd=ind;
|
|
8764
8944
|
}
|
|
8765
|
-
|
|
8766
|
-
|
|
8945
|
+
*/
|
|
8946
|
+
if (isEqual$2(compareVal, controlValue)) {
|
|
8767
8947
|
foundInd = ind;
|
|
8768
8948
|
}
|
|
8769
8949
|
});
|
|
@@ -9118,6 +9298,63 @@ class RootComponent {
|
|
|
9118
9298
|
}
|
|
9119
9299
|
sortableInit(sortable) {
|
|
9120
9300
|
this.sortableObj = sortable;
|
|
9301
|
+
///NB issue caused by sortablejs when it its destroyed
|
|
9302
|
+
//this mainly affects checkboxes coupled with conditions
|
|
9303
|
+
//-the value is rechecked
|
|
9304
|
+
//-see https://github.com/SortableJS/Sortable/issues/1052#issuecomment-369613072
|
|
9305
|
+
/* attempt to monkey patch sortable js
|
|
9306
|
+
const originalMethod = sortable._nulling;
|
|
9307
|
+
let zone=this.zone;
|
|
9308
|
+
sortable._nulling=function() {
|
|
9309
|
+
console.log(`pluginEvent 2 ${pluginEvent}`)
|
|
9310
|
+
zone.runOutsideAngular(() => {
|
|
9311
|
+
console.log(`pluginEvent3 ${pluginEvent}`)
|
|
9312
|
+
pluginEvent('nulling', this);
|
|
9313
|
+
|
|
9314
|
+
rootEl =
|
|
9315
|
+
dragEl =
|
|
9316
|
+
parentEl =
|
|
9317
|
+
ghostEl =
|
|
9318
|
+
nextEl =
|
|
9319
|
+
cloneEl =
|
|
9320
|
+
lastDownEl =
|
|
9321
|
+
cloneHidden =
|
|
9322
|
+
|
|
9323
|
+
tapEvt =
|
|
9324
|
+
touchEvt =
|
|
9325
|
+
|
|
9326
|
+
moved =
|
|
9327
|
+
newIndex =
|
|
9328
|
+
newDraggableIndex =
|
|
9329
|
+
oldIndex =
|
|
9330
|
+
oldDraggableIndex =
|
|
9331
|
+
|
|
9332
|
+
lastTarget =
|
|
9333
|
+
lastDirection =
|
|
9334
|
+
|
|
9335
|
+
putSortable =
|
|
9336
|
+
activeGroup =
|
|
9337
|
+
Sortable.dragged =
|
|
9338
|
+
Sortable.ghost =
|
|
9339
|
+
Sortable.clone =
|
|
9340
|
+
Sortable.active = null;
|
|
9341
|
+
|
|
9342
|
+
|
|
9343
|
+
let el = this.el;
|
|
9344
|
+
savedInputChecked.forEach(function (checkEl) {
|
|
9345
|
+
if (el.contains(checkEl)) {
|
|
9346
|
+
checkEl.checked = true;
|
|
9347
|
+
}
|
|
9348
|
+
});
|
|
9349
|
+
|
|
9350
|
+
savedInputChecked.length =
|
|
9351
|
+
lastDx =
|
|
9352
|
+
lastDy = 0;
|
|
9353
|
+
|
|
9354
|
+
})
|
|
9355
|
+
|
|
9356
|
+
}.bind(sortable)
|
|
9357
|
+
*/
|
|
9121
9358
|
}
|
|
9122
9359
|
isDraggable(node) {
|
|
9123
9360
|
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
|
}
|