pict-section-form 1.0.157 → 1.0.159
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/example_applications/complex_table/Complex-Tabular-Application.js +2 -1
- package/package.json +2 -2
- package/source/providers/Pict-Provider-DynamicFormSolverBehaviors.js +75 -6
- package/source/providers/Pict-Provider-DynamicTabularData.js +44 -5
- package/source/providers/inputs/Pict-Provider-Input-PreciseNumber.js +1 -1
- package/source/services/ManifestFactory.js +1 -1
- package/source/views/Pict-View-DynamicForm.js +15 -0
- package/source/views/Pict-View-Form-Metacontroller.js +2 -2
- package/test/PictSectionForm-Basic_tests.js +189 -0
- package/types/source/views/Pict-View-Form-Metacontroller.d.ts.map +1 -1
|
@@ -86,7 +86,8 @@ module.exports.default_configuration.pict_configuration = {
|
|
|
86
86
|
"RecipeCounterSurfaceArea = RecipeCounterWidth * RecipeCounterDepth",
|
|
87
87
|
"RecipeCounterVolume = RecipeCounterSurfaceArea * RecipeVerticalClearance",
|
|
88
88
|
`InspirationLink = CONCAT("https://www.google.com/search?q=", RecipeName, " recipe")`,
|
|
89
|
-
'cumulativeSummationResult = cumulativeSummation(getvalue("AppData.FruitData.FruityVice"), "nutritions.calories", "SummedCalories")'
|
|
89
|
+
'cumulativeSummationResult = cumulativeSummation(getvalue("AppData.FruitData.FruityVice"), "nutritions.calories", "SummedCalories")',
|
|
90
|
+
`MAP VAR row FROM FruitData.FruityVice : ColorInputBackgroundTabular("FruitGrid", "FruitGrid", "PercentTotalFat", stepIndex, "#FFCCCC", IF(row.nutritions.percent_total_fat, ">", 0.25, 1, 0))`,
|
|
90
91
|
],
|
|
91
92
|
|
|
92
93
|
MetaTemplates:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pict-section-form",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.159",
|
|
4
4
|
"description": "Pict dynamic form sections",
|
|
5
5
|
"main": "source/Pict-Section-Form.js",
|
|
6
6
|
"directories": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"browser-env": "^3.3.0",
|
|
35
35
|
"eslint": "^9.39.1",
|
|
36
36
|
"jquery": "^3.7.1",
|
|
37
|
-
"pict": "^1.0.
|
|
37
|
+
"pict": "^1.0.337",
|
|
38
38
|
"pict-application": "^1.0.29",
|
|
39
39
|
"pict-service-commandlineutility": "^1.0.16",
|
|
40
40
|
"quackage": "^1.0.45",
|
|
@@ -82,6 +82,7 @@ class PictDynamicFormsSolverBehaviors extends libPictProvider
|
|
|
82
82
|
this.addSolverFunction(pExpressionParser, 'colorSectionBackground', 'fable.providers.DynamicFormSolverBehaviors.colorSectionBackground', 'Colors a section background with a HTML hex color (e.g. #FF0000 for red).');
|
|
83
83
|
this.addSolverFunction(pExpressionParser, 'colorGroupBackground', 'fable.providers.DynamicFormSolverBehaviors.colorGroupBackground', 'Colors a group background with a HTML hex color (e.g. #FF0000 for red).');
|
|
84
84
|
this.addSolverFunction(pExpressionParser, 'colorInputBackground', 'fable.providers.DynamicFormSolverBehaviors.colorInputBackground', 'Colors an input background with a HTML hex color (e.g. #FF0000 for red).');
|
|
85
|
+
this.addSolverFunction(pExpressionParser, 'colorInputBackgroundTabular', 'fable.providers.DynamicFormSolverBehaviors.colorInputBackgroundTabular', 'Colors a tabular input background with a HTML hex color (e.g. #FF0000 for red).');
|
|
85
86
|
|
|
86
87
|
return false;
|
|
87
88
|
}
|
|
@@ -293,7 +294,8 @@ class PictDynamicFormsSolverBehaviors extends libPictProvider
|
|
|
293
294
|
return true;
|
|
294
295
|
}
|
|
295
296
|
|
|
296
|
-
|
|
297
|
+
/** @type {import('../views/Pict-View-DynamicForm.js')} */
|
|
298
|
+
let tmpInputView = this.pict.views.PictFormMetacontroller.getSectionViewFromHash(pSectionHash);
|
|
297
299
|
|
|
298
300
|
if (!tmpInputView)
|
|
299
301
|
{
|
|
@@ -313,22 +315,89 @@ class PictDynamicFormsSolverBehaviors extends libPictProvider
|
|
|
313
315
|
|
|
314
316
|
if (tmpElementSet.length < 1)
|
|
315
317
|
{
|
|
316
|
-
this.log.warn(`PictDynamicFormsInformary: colorInput could not find input element with section hash [${pSectionHash}] input [${pInputHash}] selector [
|
|
318
|
+
this.log.warn(`PictDynamicFormsInformary: colorInput could not find input element with section hash [${pSectionHash}] input [${pInputHash}] selector [#${tmpInput.Macro.RawHTMLID}].`);
|
|
317
319
|
return false;
|
|
318
320
|
}
|
|
319
321
|
|
|
320
|
-
|
|
322
|
+
return this.colorElementBackground(tmpElementSet, pColor, pCSSSelector);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Colors an input background or its container with a HTML hex color (e.g. #FF0000 for red).
|
|
327
|
+
* @param {string} pSectionHash - The hash of the section containing the input.
|
|
328
|
+
* @param {string} pGroupHash - The hash of the group containing the input.
|
|
329
|
+
* @param {number} pRowIndex - The index of the row.
|
|
330
|
+
* @param {string} pInputHash - The hash of the input to color.
|
|
331
|
+
* @param {string} pColor - The HTML hex color to apply (e.g. #FF0000 for red).
|
|
332
|
+
* @param {string} pApplyChange - If "0", the change will not be applied.
|
|
333
|
+
* @param {string} [pCSSSelector] - Optional. If provided, the color will be applied to the closest element matching this selector instead of the input itself.
|
|
334
|
+
* @param {string} [pElementIDPrefix] - Optional. The prefix for the tabular element ID. Default is 'TABULAR-DATA-'.
|
|
335
|
+
* @returns {boolean} - Returns true if the color was applied successfully or if the change was skipped for pApplyChange equal to "0", false otherwise.
|
|
336
|
+
*/
|
|
337
|
+
colorInputBackgroundTabular(pSectionHash, pGroupHash, pInputHash, pRowIndex, pColor, pApplyChange, pCSSSelector, pElementIDPrefix = 'TABULAR-DATA-')
|
|
338
|
+
{
|
|
339
|
+
if (pApplyChange == "0")
|
|
340
|
+
{
|
|
341
|
+
return true;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/** @type {import('../views/Pict-View-DynamicForm.js')} */
|
|
345
|
+
let tmpInputView = this.pict.views.PictFormMetacontroller.getSectionViewFromHash(pSectionHash);
|
|
346
|
+
|
|
347
|
+
if (!tmpInputView)
|
|
348
|
+
{
|
|
349
|
+
this.log.warn(`PictDynamicFormsInformary: colorInputBackgroundTabular could not find input with section hash [${pSectionHash}] group hash [${pGroupHash}] input hash [${pInputHash}].`);
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
let tmpInput = tmpInputView.getTabularRecordInputByHash(pGroupHash, pInputHash);
|
|
354
|
+
|
|
355
|
+
if (!tmpInput)
|
|
356
|
+
{
|
|
357
|
+
this.log.warn(`PictDynamicFormsInformary: colorInputBackgroundTabular could not find input with section hash [${pSectionHash}] group hash [${pGroupHash}] input hash [${pInputHash}].`);
|
|
358
|
+
return false;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
if (!tmpInput.Macro)
|
|
362
|
+
{
|
|
363
|
+
this.log.warn(`PictDynamicFormsInformary: colorInputBackgroundTabular input with section hash [${pSectionHash}] group hash [${pGroupHash}] input hash [${pInputHash}] is missing Macro data.`);
|
|
364
|
+
return false;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
//FIXME: is this reliable for all input types?
|
|
368
|
+
let tmpElementSet = this.pict.ContentAssignment.getElement(`#${pElementIDPrefix}${tmpInput.Macro.RawHTMLID}-${pRowIndex}`);
|
|
369
|
+
|
|
370
|
+
if (tmpElementSet.length < 1)
|
|
371
|
+
{
|
|
372
|
+
this.log.warn(`PictDynamicFormsInformary: colorInputBackgroundTabular could not find input element with section hash [${pSectionHash}] group hash [${pGroupHash}] input hash [${pInputHash}] row index [${pRowIndex}] selector [#${tmpInput.Macro.RawHTMLID}-${pRowIndex}].`);
|
|
373
|
+
return false;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
return this.colorElementBackground(tmpElementSet, pColor, pCSSSelector);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* @param {Array<HTMLElement>} pElementSet - The element to color.
|
|
381
|
+
* @param {string} pColor - The HTML hex color to apply (e.g. #FF0000 for red).
|
|
382
|
+
* @param {string} [pCSSSelector] - Optional. If provided, the color will be applied to the closest element matching this selector instead of the input itself.
|
|
383
|
+
*
|
|
384
|
+
* @returns {boolean}
|
|
385
|
+
*/
|
|
386
|
+
colorElementBackground(pElementSet, pColor, pCSSSelector)
|
|
387
|
+
{
|
|
388
|
+
/** @type {HTMLElement} */
|
|
389
|
+
let tmpElement = pElementSet[0];
|
|
321
390
|
|
|
322
391
|
// if we passed a class target, find the closest element with that class and apply the color to it
|
|
323
392
|
// otherwise, just apply it to the input element itself
|
|
324
393
|
if (pCSSSelector)
|
|
325
394
|
{
|
|
326
395
|
// find closest target by class name and if we find it, immediately break out of the loop
|
|
327
|
-
for (let i = 0; i <
|
|
396
|
+
for (let i = 0; i < pElementSet.length; i++)
|
|
328
397
|
{
|
|
329
|
-
const element =
|
|
398
|
+
const element = pElementSet[i];
|
|
330
399
|
const closest = element.closest(`${pCSSSelector}`);
|
|
331
|
-
if (closest)
|
|
400
|
+
if (closest && closest instanceof HTMLElement)
|
|
332
401
|
{
|
|
333
402
|
tmpElement = closest;
|
|
334
403
|
break;
|
|
@@ -78,7 +78,7 @@ class DynamicTabularData extends libPictProvider
|
|
|
78
78
|
|
|
79
79
|
if (!tmpGroup)
|
|
80
80
|
{
|
|
81
|
-
this.log.warn(`PICT View Metatemplate Helper
|
|
81
|
+
this.log.warn(`PICT View Metatemplate Helper getTabularRecordInput ${pGroupIndex} was not a valid group.`);
|
|
82
82
|
return false;
|
|
83
83
|
}
|
|
84
84
|
|
|
@@ -88,6 +88,45 @@ class DynamicTabularData extends libPictProvider
|
|
|
88
88
|
return tmpGroup.supportingManifest.elementDescriptors[tmpSupportingManifestHash];
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Retrieves the tabular record input from the specified view, group, and input indexes.
|
|
93
|
+
*
|
|
94
|
+
* @param {Object} pView - The view object.
|
|
95
|
+
* @param {number} pGroupHash - The index of the group.
|
|
96
|
+
* @param {number} pInputHash - The index of the input.
|
|
97
|
+
* @returns {ElementDescriptor|boolean} The tabular record input or false if the group is invalid.
|
|
98
|
+
*/
|
|
99
|
+
getTabularRecordInputByHash(pView, pGroupHash, pInputHash)
|
|
100
|
+
{
|
|
101
|
+
// The neat thing about how the tabular groups work is that we can make it clever about whether it's an object or an array.
|
|
102
|
+
let tmpGroup = pView.getGroups().find((pGroup) => pGroup.Hash === pGroupHash);
|
|
103
|
+
|
|
104
|
+
if (!tmpGroup)
|
|
105
|
+
{
|
|
106
|
+
this.log.warn(`PICT View Metatemplate Helper getTabularRecordInputByHash ${pGroupHash} was not a valid group.`);
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (!tmpGroup.supportingManifest)
|
|
111
|
+
{
|
|
112
|
+
this.log.warn(`PICT View Metatemplate Helper getTabularRecordInputByHash ${pGroupHash} s not a tabular group.`);
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Now get the supporting manifest and the input element
|
|
117
|
+
// This needs more guards
|
|
118
|
+
for (const tmpDescriptor of Object.values(tmpGroup.supportingManifest.elementDescriptors))
|
|
119
|
+
{
|
|
120
|
+
if (tmpDescriptor.Hash === pInputHash)
|
|
121
|
+
{
|
|
122
|
+
return tmpDescriptor;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
this.log.warn(`PICT View Metatemplate Helper getTabularRecordInputByHash ${pGroupHash} could not find input ${pInputHash}.`);
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
|
|
91
130
|
/**
|
|
92
131
|
* Retrieves tabular record data based on the provided parameters.
|
|
93
132
|
*
|
|
@@ -103,7 +142,7 @@ class DynamicTabularData extends libPictProvider
|
|
|
103
142
|
|
|
104
143
|
if (!tmpGroup)
|
|
105
144
|
{
|
|
106
|
-
this.log.warn(`PICT View Metatemplate Helper
|
|
145
|
+
this.log.warn(`PICT View Metatemplate Helper getTabularRecordData ${pGroupIndex} was not a valid group.`);
|
|
107
146
|
return false;
|
|
108
147
|
}
|
|
109
148
|
|
|
@@ -118,7 +157,7 @@ class DynamicTabularData extends libPictProvider
|
|
|
118
157
|
|
|
119
158
|
if (!tmpRowSourceRecord)
|
|
120
159
|
{
|
|
121
|
-
this.log.warn(`PICT View Metatemplate Helper
|
|
160
|
+
this.log.warn(`PICT View Metatemplate Helper getTabularRecordData ${pGroupIndex} could not find the record set for ${tmpGroup.RecordSetAddress}.`);
|
|
122
161
|
return false;
|
|
123
162
|
}
|
|
124
163
|
|
|
@@ -135,13 +174,13 @@ class DynamicTabularData extends libPictProvider
|
|
|
135
174
|
}
|
|
136
175
|
else
|
|
137
176
|
{
|
|
138
|
-
this.log.warn(`PICT View Metatemplate Helper
|
|
177
|
+
this.log.warn(`PICT View Metatemplate Helper getTabularRecordData ${pGroupIndex} could not determine the type of the record set for ${tmpGroup.RecordSetAddress}.`);
|
|
139
178
|
return false;
|
|
140
179
|
}
|
|
141
180
|
}
|
|
142
181
|
catch (pError)
|
|
143
182
|
{
|
|
144
|
-
this.log.error(`PICT View Metatemplate Helper
|
|
183
|
+
this.log.error(`PICT View Metatemplate Helper getTabularRecordData ${pGroupIndex} encountered an error: ${pError}`);
|
|
145
184
|
return false;
|
|
146
185
|
}
|
|
147
186
|
}
|
|
@@ -91,7 +91,7 @@ class CustomInputHandler extends libPictSectionInputExtension
|
|
|
91
91
|
*/
|
|
92
92
|
onDataMarshalToFormTabular(pView, pGroup, pInput, pValue, pHTMLSelector, pRowIndex, pTransactionGUID)
|
|
93
93
|
{
|
|
94
|
-
this.pict.ContentAssignment.assignContent('PRECISE-' + this.getTabularInputHTMLID(pInput.Macro.RawHTMLID, pRowIndex), pValue);
|
|
94
|
+
this.pict.ContentAssignment.assignContent('#PRECISE-' + this.getTabularInputHTMLID(pInput.Macro.RawHTMLID, pRowIndex).substring(1), pValue);
|
|
95
95
|
this.pict.ContentAssignment.assignContent(this.getTabularInputHTMLID(pInput.Macro.RawHTMLID, pRowIndex), this.roundValue(pInput, pValue));
|
|
96
96
|
return super.onDataMarshalToFormTabular(pView, pGroup, pInput, pValue, pHTMLSelector, pRowIndex, pTransactionGUID);
|
|
97
97
|
}
|
|
@@ -875,7 +875,7 @@ class ManifestFactory extends libFableServiceProviderBase
|
|
|
875
875
|
{
|
|
876
876
|
tmpDescriptorManifest.setValueAtAddress(tmpDescriptor, tmpAddress, tmpValue);
|
|
877
877
|
}
|
|
878
|
-
else
|
|
878
|
+
else if (tmpRawValue)
|
|
879
879
|
{
|
|
880
880
|
this.log.warn(`Could not parse Boolean value [${tmpRawValue}] for Descriptor Boolean Extension [${tmpKey}] on descriptor [${tmpDescriptor.Hash}]`);
|
|
881
881
|
}
|
|
@@ -1369,6 +1369,21 @@ class PictViewDynamicForm extends libPictViewClass
|
|
|
1369
1369
|
return this.pict.providers.DynamicTabularData.getTabularRecordInput(this, pGroupIndex, pInputIndex);
|
|
1370
1370
|
}
|
|
1371
1371
|
|
|
1372
|
+
/**
|
|
1373
|
+
* Get the input object for a specific tabular record group and index.
|
|
1374
|
+
*
|
|
1375
|
+
* Input objects are not distinct among rows.
|
|
1376
|
+
*
|
|
1377
|
+
* @param {string} pGroupHash - The hash of the group.
|
|
1378
|
+
* @param {string} pInputHash - The hash of the input.
|
|
1379
|
+
*
|
|
1380
|
+
* @return {Object} The input object.
|
|
1381
|
+
*/
|
|
1382
|
+
getTabularRecordInputByHash(pGroupHash, pInputHash)
|
|
1383
|
+
{
|
|
1384
|
+
return this.pict.providers.DynamicTabularData.getTabularRecordInputByHash(this, pGroupHash, pInputHash);
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1372
1387
|
/**
|
|
1373
1388
|
* Get the tabular record object for a particular row in a group.
|
|
1374
1389
|
*
|
|
@@ -473,9 +473,9 @@ class PictFormMetacontroller extends libPictViewClass
|
|
|
473
473
|
//FIXME: do we want to allow prefixing the data address? (ex. nesting it under a parent object) - caller can still do this themselves.
|
|
474
474
|
tmpRecordSetAddress = `${tmpGroup.RecordSetAddress}_${tmpUUID}`;
|
|
475
475
|
}
|
|
476
|
-
//TODO: does this need to go into the mappings?
|
|
477
|
-
tmpGroup.RecordSetAddress = tmpRecordSetAddress;
|
|
478
476
|
}
|
|
477
|
+
//TODO: does this need to go into the mappings if it isn't there?
|
|
478
|
+
tmpGroup.RecordSetAddress = tmpRecordSetAddress;
|
|
479
479
|
|
|
480
480
|
}
|
|
481
481
|
if (Array.isArray(tmpGroup.RecordSetSolvers) && tmpGroup.RecordSetSolvers.length > 0)
|
|
@@ -692,6 +692,195 @@ suite
|
|
|
692
692
|
}
|
|
693
693
|
);
|
|
694
694
|
test(
|
|
695
|
+
'Distinct Array Test 4',
|
|
696
|
+
(fDone) =>
|
|
697
|
+
{
|
|
698
|
+
//NOTE: code is a clone of Pict.safeLoadPictApplication
|
|
699
|
+
let _Pict;
|
|
700
|
+
const tmpApplicationClass = OrderedSolverApplication;
|
|
701
|
+
if (tmpApplicationClass && ('default_configuration' in tmpApplicationClass) && ('pict_configuration' in tmpApplicationClass.default_configuration))
|
|
702
|
+
{
|
|
703
|
+
_Pict = new libPict(tmpApplicationClass.default_configuration.pict_configuration);
|
|
704
|
+
}
|
|
705
|
+
else
|
|
706
|
+
{
|
|
707
|
+
_Pict = new libPict();
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
//_Pict.LogNoisiness = 0;
|
|
711
|
+
|
|
712
|
+
let tmpApplicationHash = 'DefaultApplication';
|
|
713
|
+
let tmpDefaultConfiguration = {};
|
|
714
|
+
|
|
715
|
+
if ('default_configuration' in tmpApplicationClass)
|
|
716
|
+
{
|
|
717
|
+
tmpDefaultConfiguration = tmpApplicationClass.default_configuration;
|
|
718
|
+
|
|
719
|
+
if ('Hash' in tmpApplicationClass.default_configuration)
|
|
720
|
+
{
|
|
721
|
+
tmpDefaultConfiguration = tmpApplicationClass.default_configuration;
|
|
722
|
+
tmpApplicationHash = tmpApplicationClass.default_configuration.Hash;
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
_Pict.log.info(`Loading the pict application [${tmpApplicationHash}] and associated views.`);
|
|
726
|
+
|
|
727
|
+
_Pict.addApplication(tmpApplicationHash, tmpDefaultConfiguration, tmpApplicationClass);
|
|
728
|
+
|
|
729
|
+
// Add the pict form service
|
|
730
|
+
_Pict.addServiceType('PictSectionForm', libPictSectionForm);
|
|
731
|
+
|
|
732
|
+
// Add the pict form metacontroller service, which provides programmaatic view construction from manifests and render/marshal methods.
|
|
733
|
+
_Pict.addView('PictFormMetacontroller', {}, libPictSectionForm.PictFormMetacontroller);
|
|
734
|
+
|
|
735
|
+
const tmpManifest =
|
|
736
|
+
{
|
|
737
|
+
Scope: 'OrderedSolverApplicationForm',
|
|
738
|
+
Descriptors:
|
|
739
|
+
{
|
|
740
|
+
'LevelOfIndirection.DataTableAddress':
|
|
741
|
+
{
|
|
742
|
+
Hash: 'NestedDataTable',
|
|
743
|
+
Name: 'Nested Data Table',
|
|
744
|
+
DataAddress: 'LevelOfIndirection.DataTableAddress',
|
|
745
|
+
DataType: 'Array',
|
|
746
|
+
FormGroup: 'DataTableGroup',
|
|
747
|
+
FormSection: 'DataTableSection',
|
|
748
|
+
},
|
|
749
|
+
'LevelOfIndirection.AggregateValueAddress':
|
|
750
|
+
{
|
|
751
|
+
Hash: 'IndirectAggregateValue',
|
|
752
|
+
Name: 'Indirect Aggregate Value',
|
|
753
|
+
DataAddress: 'LevelOfIndirection.AggregateValueAddress',
|
|
754
|
+
DataType: 'PreciseNumber',
|
|
755
|
+
FormGroup: 'DataTableGroup',
|
|
756
|
+
FormSection: 'DataTableSection',
|
|
757
|
+
},
|
|
758
|
+
'LevelOfIndirection.DataTableAddress[].ValueAddress':
|
|
759
|
+
{
|
|
760
|
+
Hash: 'ValueArray',
|
|
761
|
+
Name: 'Data Value',
|
|
762
|
+
DataAddress: 'LevelOfIndirection.DataTableAddress[].ValueAddress',
|
|
763
|
+
DataType: 'Array',
|
|
764
|
+
FormGroup: 'DataTableGroup',
|
|
765
|
+
FormSection: 'DataTableSection',
|
|
766
|
+
},
|
|
767
|
+
AggregateValueAddress:
|
|
768
|
+
{
|
|
769
|
+
Hash: 'AggregateValue',
|
|
770
|
+
Name: 'Aggregate Value',
|
|
771
|
+
DataAddress: 'AggregateValueAddress',
|
|
772
|
+
DataType: 'PreciseNumber',
|
|
773
|
+
FormGroup: 'DataTableGroup',
|
|
774
|
+
FormSection: 'DataTableSection',
|
|
775
|
+
},
|
|
776
|
+
AggregateValueAddress2:
|
|
777
|
+
{
|
|
778
|
+
Hash: 'AggregateValue2',
|
|
779
|
+
Name: 'Aggregate Value 2',
|
|
780
|
+
DataAddress: 'AggregateValueAddress2',
|
|
781
|
+
DataType: 'PreciseNumber',
|
|
782
|
+
FormGroup: 'DataTableGroup',
|
|
783
|
+
FormSection: 'DataTableSection',
|
|
784
|
+
},
|
|
785
|
+
},
|
|
786
|
+
Sections:
|
|
787
|
+
[
|
|
788
|
+
{
|
|
789
|
+
Name: 'Ordered Solver Section',
|
|
790
|
+
Hash: 'OrderedSolverSection',
|
|
791
|
+
Groups:
|
|
792
|
+
[
|
|
793
|
+
{
|
|
794
|
+
Name: 'Group Name',
|
|
795
|
+
Hash: 'GroupHash',
|
|
796
|
+
RecordSetAddress: 'LevelOfIndirection.DataTableAddress',
|
|
797
|
+
},
|
|
798
|
+
],
|
|
799
|
+
Solvers:
|
|
800
|
+
[
|
|
801
|
+
{ Ordinal: 5, Expression: 'AggregateValue = SUM(ValueArray)' },
|
|
802
|
+
{ Ordinal: 40, Expression: 'AggregateValue2 = SUM(LevelOfIndirection.DataTableAddress[].ValueAddress)' },
|
|
803
|
+
{ Ordinal: 60, Expression: 'IndirectAggregateValue = AggregateValue' },
|
|
804
|
+
],
|
|
805
|
+
},
|
|
806
|
+
],
|
|
807
|
+
};
|
|
808
|
+
|
|
809
|
+
let tmpHashedAggregateValue = null;
|
|
810
|
+
let tmpHashedAggregateValue2 = null;
|
|
811
|
+
let tmpHashedAggregateValue3 = null;
|
|
812
|
+
_Pict.PictApplication.initializeAsync(
|
|
813
|
+
function (pError)
|
|
814
|
+
{
|
|
815
|
+
if (pError)
|
|
816
|
+
{
|
|
817
|
+
_Pict.log.info('Error initializing the pict application: '+pError)
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
try
|
|
821
|
+
{
|
|
822
|
+
_Pict.log.info('Loading the Application and associated views.');
|
|
823
|
+
const tmpUUID = _Pict.getUUID().substring(0, 8);
|
|
824
|
+
const tmpDistinctManifest = _Pict.views.PictFormMetacontroller.createDistinctManifest(tmpManifest, tmpUUID);
|
|
825
|
+
_Pict.log.info('Distinct Manifest:', tmpDistinctManifest);
|
|
826
|
+
Expect(tmpDistinctManifest.Sections[0].Groups[0].RecordSetAddress).to.equal(`LevelOfIndirection_${tmpUUID}.DataTableAddress`, 'Group RecordSetAddress should be preserved in distinct manifest.');
|
|
827
|
+
tmpHashedAggregateValue = Object.entries(tmpDistinctManifest.Descriptors).find(([pKey, pValue]) => pValue.OriginalHash == 'AggregateValue')[0];
|
|
828
|
+
tmpHashedAggregateValue2 = Object.entries(tmpDistinctManifest.Descriptors).find(([pKey, pValue]) => pValue.OriginalHash == 'AggregateValue2')[0];
|
|
829
|
+
tmpHashedAggregateValue3 = Object.entries(tmpDistinctManifest.Descriptors).find(([pKey, pValue]) => pValue.OriginalHash == 'IndirectAggregateValue')[0];
|
|
830
|
+
const tmpInjectedSecionViews = _Pict.views.PictFormMetacontroller.injectManifest(tmpDistinctManifest);
|
|
831
|
+
_Pict.log.info('Injected Section Views:', tmpInjectedSecionViews.length);
|
|
832
|
+
_Pict.views.PictFormMetacontroller.updateMetatemplateInDOM();
|
|
833
|
+
setTimeout(() =>
|
|
834
|
+
{
|
|
835
|
+
for (const tmpView of tmpInjectedSecionViews)
|
|
836
|
+
{
|
|
837
|
+
tmpView.render();
|
|
838
|
+
}
|
|
839
|
+
for (const tmpView of tmpInjectedSecionViews)
|
|
840
|
+
{
|
|
841
|
+
tmpView.marshalToView();
|
|
842
|
+
}
|
|
843
|
+
//TODO: do we need to trigger a solve here?
|
|
844
|
+
}, 0);
|
|
845
|
+
_Pict.PictApplication.testDone = () =>
|
|
846
|
+
{
|
|
847
|
+
try
|
|
848
|
+
{
|
|
849
|
+
_Pict.log.info(`AppData after`, { AppData: _Pict.AppData, tmpHashedAggregateValue, tmpHashedAggregateValue2, tmpHashedAggregateValue3 });
|
|
850
|
+
Expect(_Pict.AppData[tmpHashedAggregateValue]).to.equal('15', 'AggregateValue should equal 15 (SUM of ValueArray via hash)');
|
|
851
|
+
Expect(_Pict.AppData[tmpHashedAggregateValue2]).to.equal('15', 'AggregateValue should equal 15 (SUM of ValueArray via address)');
|
|
852
|
+
Expect(_Pict.manifest.getValueByHash(_Pict.AppData, tmpHashedAggregateValue3)).to.equal('15', 'IndirectAggregateValue should equal 15 (via indirection) using manifest method');
|
|
853
|
+
}
|
|
854
|
+
catch (pError)
|
|
855
|
+
{
|
|
856
|
+
return fDone(pError);
|
|
857
|
+
}
|
|
858
|
+
fDone();
|
|
859
|
+
};
|
|
860
|
+
const [ tmpValueArrayKey, tmpValueArrayDescriptor ] = Object.entries(tmpDistinctManifest.Descriptors).find(([pKey, pDescriptor]) => pDescriptor.OriginalHash == 'ValueArray');
|
|
861
|
+
const tmpAddress = tmpValueArrayDescriptor.DataAddress;
|
|
862
|
+
_Pict.log.info('Setting up Distinct Array Test with address:', { tmpValueArrayKey, tmpValueArrayDescriptor, tmpAddress });
|
|
863
|
+
const tmpArrayAddress = tmpAddress.substring(0, tmpAddress.indexOf('[]'));
|
|
864
|
+
const tmpPropertyAddress = tmpAddress.substring(tmpAddress.indexOf('[]') + 3);
|
|
865
|
+
_Pict.manifest.setValueByHash(_Pict.AppData, tmpArrayAddress,
|
|
866
|
+
[
|
|
867
|
+
{ [tmpPropertyAddress]: '1' },
|
|
868
|
+
{ [tmpPropertyAddress]: '2' },
|
|
869
|
+
{ [tmpPropertyAddress]: '3' },
|
|
870
|
+
{ [tmpPropertyAddress]: '4' },
|
|
871
|
+
{ [tmpPropertyAddress]: '5' },
|
|
872
|
+
]);
|
|
873
|
+
_Pict.PictApplication.solve();
|
|
874
|
+
}
|
|
875
|
+
catch (pError)
|
|
876
|
+
{
|
|
877
|
+
_Pict.log.error('Error during Distinct Array Test:', pError);
|
|
878
|
+
return fDone(pError);
|
|
879
|
+
}
|
|
880
|
+
});
|
|
881
|
+
}
|
|
882
|
+
);
|
|
883
|
+
test(
|
|
695
884
|
'Solve Ordinals',
|
|
696
885
|
(fDone) =>
|
|
697
886
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Pict-View-Form-Metacontroller.d.ts","sourceRoot":"","sources":["../../../source/views/Pict-View-Form-Metacontroller.js"],"names":[],"mappings":";AAaA;;GAEG;AAEH;;;;;;GAMG;AACH;IAEC,2DAyBC;IAjBA,yBAA2B;IAE3B,wBAAsF;IAEtF,cAAkC;IAElC,gCAAkC;IAClC,8BAAiC;IAEjC;;;;;;MAOE;IAQH,wCAGC;IARD,kCAGC;IAOD;;;;OAIG;IACH,qBAFa,GAAG,CAaf;IAED;;;;OAIG;IACH,mBAFa,GAAG,CAaf;IAED,yCAYC;IAED;;;;;OAKG;IACH,kCAHW,aAAa,GACX,IAAI,CAsBhB;IA8BD;;;;OAIG;IACH,WAFa,GAAG,CAMf;IAED,kCAGC;IAED,gDAGC;IAED,+CAGC;IAED;;;;OAIG;IACH,2DAJW,MAAM,GAEL,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAW9B;IAED;;;;;;OAMG;IACH,mCANW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,sBACnB,MAAM,UACN,MAAM,GAEL,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC,CAwBtD;IAED;;;;;OAKG;IACH,0BALW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,sBACnB,MAAM,GAEL,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC,CAgCtD;IAED;;;;;;;;;OASG;IACH,kCALW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,UACnB,MAAM,GAEL,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"Pict-View-Form-Metacontroller.d.ts","sourceRoot":"","sources":["../../../source/views/Pict-View-Form-Metacontroller.js"],"names":[],"mappings":";AAaA;;GAEG;AAEH;;;;;;GAMG;AACH;IAEC,2DAyBC;IAjBA,yBAA2B;IAE3B,wBAAsF;IAEtF,cAAkC;IAElC,gCAAkC;IAClC,8BAAiC;IAEjC;;;;;;MAOE;IAQH,wCAGC;IARD,kCAGC;IAOD;;;;OAIG;IACH,qBAFa,GAAG,CAaf;IAED;;;;OAIG;IACH,mBAFa,GAAG,CAaf;IAED,yCAYC;IAED;;;;;OAKG;IACH,kCAHW,aAAa,GACX,IAAI,CAsBhB;IA8BD;;;;OAIG;IACH,WAFa,GAAG,CAMf;IAED,kCAGC;IAED,gDAGC;IAED,+CAGC;IAED;;;;OAIG;IACH,2DAJW,MAAM,GAEL,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAW9B;IAED;;;;;;OAMG;IACH,mCANW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,sBACnB,MAAM,UACN,MAAM,GAEL,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC,CAwBtD;IAED;;;;;OAKG;IACH,0BALW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,sBACnB,MAAM,GAEL,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC,CAgCtD;IAED;;;;;;;;;OASG;IACH,kCALW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,UACnB,MAAM,GAEL,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAqO9B;IAED;;;;OAIG;IACH,uCAJW,KAAK,CAAC,MAAM,CAAC,sBACb,MAAM,UACN,MAAM,QAuBhB;IAED;;;OAGG;IACH,6CAHW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,sBACnB,MAAM,SAehB;IAED;;;;;;;;OAQG;IACH,wDAHW,YAAY,SAoHtB;IAED;;;;;;;OAOG;IACH,4CAHW,MAAM,GACJ,IAAI,CAShB;IAED;;;;OAIG;IACH,6BAFa,IAAI,CAQhB;IAED;;;;;;;OAOG;IACH,+DAFW,YAAY,QAatB;IAED;;;;;;;OAOG;IACH,gEAFW,YAAY,QAatB;IAED;;;;;OAKG;IACH,8EAFW,YAAY,QAmBtB;IAED;;;;;;OAMG;IACH,oEAHW,YAAY,GACV,IAAI,CAkDhB;IAED;;;;;;;OAOG;IACH,uEAJW,YAAY,GAEX,IAAI,CAsFf;IAED;;;;;OAKG;IACH,qCAHW,MAAM,GACJ,MAAM,GAAC,OAAO,CA2C1B;IAED,+CAeC;IAED;;;;;;;OAOG;IACH,kFAJW,MAAM,GAEJ,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAoLtC;IA5JC,gCAA0D;IAC1D,yBAAiD;IA6JnD;;;;OAIG;IACH,gCAHW,MAAM,qBACN,MAAM,QA0BhB;IAED;;;OAGG;IACH,yDAHW,MAAM,uBACN,MAAM,QAKhB;IAED;;;;;OAKG;IACH,yDALW,MAAM,uBACN,MAAM,GAEL,OAAO,CAoDlB;IAED;;;;OAIG;IACH,sCAJW,MAAM,GAEL,OAAO,CA0ClB;IAED;;;OAGG;IACH,wDAHW,MAAM,6BAuBhB;IAED,oCAgBC;IAED;;;;OAIG;IACH,4BAFa,OAAO,CAKnB;CACD;;;;;qCAGU,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;oBAn2CjB,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,KAAK,MAAM"}
|