pict-section-recordset 1.0.24 → 1.0.26

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.
Files changed (98) hide show
  1. package/example_applications/simple_entity/Simple-RecordSet-Application.js +170 -110
  2. package/package.json +7 -7
  3. package/source/application/Pict-Application-RecordSet.js +8 -0
  4. package/source/providers/RecordSet-Link-Manager.js +2 -2
  5. package/source/providers/RecordSet-RecordProvider-Base.js +9 -2
  6. package/source/providers/RecordSet-RecordProvider-MeadowEndpoints.js +116 -14
  7. package/source/services/RecordsSet-MetaController.js +41 -19
  8. package/source/templates/Pict-Template-FilterInstanceViews.js +222 -0
  9. package/source/templates/Pict-Template-FilterView.js +4 -2
  10. package/source/views/RecordSet-Filters.js +449 -0
  11. package/source/views/dashboard/RecordSet-Dashboard.js +65 -8
  12. package/source/views/filters/RecordSet-Filter-Base-Range.js +38 -0
  13. package/source/views/filters/RecordSet-Filter-Base.js +88 -0
  14. package/source/views/filters/RecordSet-Filter-DateMatch.js +56 -0
  15. package/source/views/filters/RecordSet-Filter-DateRange.js +75 -0
  16. package/source/views/filters/RecordSet-Filter-ExternalJoinDateMatch.js +55 -0
  17. package/source/views/filters/RecordSet-Filter-ExternalJoinDateRange.js +57 -0
  18. package/source/views/filters/RecordSet-Filter-ExternalJoinNumericMatch.js +54 -0
  19. package/source/views/filters/RecordSet-Filter-ExternalJoinNumericRange.js +57 -0
  20. package/source/views/filters/RecordSet-Filter-ExternalJoinStringMatch.js +45 -0
  21. package/source/views/filters/RecordSet-Filter-ExternalJoinStringRange.js +46 -0
  22. package/source/views/filters/RecordSet-Filter-InternalJoinDateMatch.js +55 -0
  23. package/source/views/filters/RecordSet-Filter-InternalJoinDateRange.js +57 -0
  24. package/source/views/filters/RecordSet-Filter-InternalJoinNumericMatch.js +55 -0
  25. package/source/views/filters/RecordSet-Filter-InternalJoinNumericRange.js +57 -0
  26. package/source/views/filters/RecordSet-Filter-InternalJoinStringMatch.js +45 -0
  27. package/source/views/filters/RecordSet-Filter-InternalJoinStringRange.js +46 -0
  28. package/source/views/filters/RecordSet-Filter-NumericMatch.js +55 -0
  29. package/source/views/filters/RecordSet-Filter-NumericRange.js +57 -0
  30. package/source/views/filters/RecordSet-Filter-StringMatch.js +45 -0
  31. package/source/views/filters/RecordSet-Filter-StringRange.js +46 -0
  32. package/source/views/filters/index.js +27 -0
  33. package/source/views/list/RecordSet-List.js +44 -6
  34. package/test/PictSectionRecordSet-RecordProvider-Meadow_tests.js +11 -0
  35. package/types/application/Pict-Application-RecordSet.d.ts.map +1 -1
  36. package/types/providers/RecordSet-DynamicRecordsetSolver.d.ts +6 -6
  37. package/types/providers/RecordSet-DynamicRecordsetSolver.d.ts.map +1 -1
  38. package/types/providers/RecordSet-Link-Manager.d.ts +3 -3
  39. package/types/providers/RecordSet-RecordProvider-Base.d.ts +9 -0
  40. package/types/providers/RecordSet-RecordProvider-Base.d.ts.map +1 -1
  41. package/types/providers/RecordSet-RecordProvider-MeadowEndpoints.d.ts +30 -4
  42. package/types/providers/RecordSet-RecordProvider-MeadowEndpoints.d.ts.map +1 -1
  43. package/types/services/RecordsSet-MetaController.d.ts +2 -2
  44. package/types/services/RecordsSet-MetaController.d.ts.map +1 -1
  45. package/types/templates/Pict-Template-FilterInstanceViews.d.ts +19 -0
  46. package/types/templates/Pict-Template-FilterInstanceViews.d.ts.map +1 -0
  47. package/types/templates/Pict-Template-FilterView.d.ts.map +1 -1
  48. package/types/views/RecordSet-Filters.d.ts +84 -0
  49. package/types/views/RecordSet-Filters.d.ts.map +1 -0
  50. package/types/views/dashboard/RecordSet-Dashboard.d.ts +4 -2
  51. package/types/views/dashboard/RecordSet-Dashboard.d.ts.map +1 -1
  52. package/types/views/filters/RecordSet-Filter-Base-Range.d.ts +5 -0
  53. package/types/views/filters/RecordSet-Filter-Base-Range.d.ts.map +1 -0
  54. package/types/views/filters/RecordSet-Filter-Base.d.ts +29 -0
  55. package/types/views/filters/RecordSet-Filter-Base.d.ts.map +1 -0
  56. package/types/views/filters/RecordSet-Filter-DateMatch.d.ts +9 -0
  57. package/types/views/filters/RecordSet-Filter-DateMatch.d.ts.map +1 -0
  58. package/types/views/filters/RecordSet-Filter-DateRange.d.ts +9 -0
  59. package/types/views/filters/RecordSet-Filter-DateRange.d.ts.map +1 -0
  60. package/types/views/filters/RecordSet-Filter-ExternalJoinDateMatch.d.ts +9 -0
  61. package/types/views/filters/RecordSet-Filter-ExternalJoinDateMatch.d.ts.map +1 -0
  62. package/types/views/filters/RecordSet-Filter-ExternalJoinDateRange.d.ts +9 -0
  63. package/types/views/filters/RecordSet-Filter-ExternalJoinDateRange.d.ts.map +1 -0
  64. package/types/views/filters/RecordSet-Filter-ExternalJoinNumericMatch.d.ts +9 -0
  65. package/types/views/filters/RecordSet-Filter-ExternalJoinNumericMatch.d.ts.map +1 -0
  66. package/types/views/filters/RecordSet-Filter-ExternalJoinNumericRange.d.ts +9 -0
  67. package/types/views/filters/RecordSet-Filter-ExternalJoinNumericRange.d.ts.map +1 -0
  68. package/types/views/filters/RecordSet-Filter-ExternalJoinStringMatch.d.ts +9 -0
  69. package/types/views/filters/RecordSet-Filter-ExternalJoinStringMatch.d.ts.map +1 -0
  70. package/types/views/filters/RecordSet-Filter-ExternalJoinStringRange.d.ts +9 -0
  71. package/types/views/filters/RecordSet-Filter-ExternalJoinStringRange.d.ts.map +1 -0
  72. package/types/views/filters/RecordSet-Filter-InternalJoinDateMatch.d.ts +9 -0
  73. package/types/views/filters/RecordSet-Filter-InternalJoinDateMatch.d.ts.map +1 -0
  74. package/types/views/filters/RecordSet-Filter-InternalJoinDateRange.d.ts +9 -0
  75. package/types/views/filters/RecordSet-Filter-InternalJoinDateRange.d.ts.map +1 -0
  76. package/types/views/filters/RecordSet-Filter-InternalJoinNumericMatch.d.ts +9 -0
  77. package/types/views/filters/RecordSet-Filter-InternalJoinNumericMatch.d.ts.map +1 -0
  78. package/types/views/filters/RecordSet-Filter-InternalJoinNumericRange.d.ts +9 -0
  79. package/types/views/filters/RecordSet-Filter-InternalJoinNumericRange.d.ts.map +1 -0
  80. package/types/views/filters/RecordSet-Filter-InternalJoinStringMatch.d.ts +9 -0
  81. package/types/views/filters/RecordSet-Filter-InternalJoinStringMatch.d.ts.map +1 -0
  82. package/types/views/filters/RecordSet-Filter-InternalJoinStringRange.d.ts +9 -0
  83. package/types/views/filters/RecordSet-Filter-InternalJoinStringRange.d.ts.map +1 -0
  84. package/types/views/filters/RecordSet-Filter-NumericMatch.d.ts +9 -0
  85. package/types/views/filters/RecordSet-Filter-NumericMatch.d.ts.map +1 -0
  86. package/types/views/filters/RecordSet-Filter-NumericRange.d.ts +9 -0
  87. package/types/views/filters/RecordSet-Filter-NumericRange.d.ts.map +1 -0
  88. package/types/views/filters/RecordSet-Filter-StringMatch.d.ts +9 -0
  89. package/types/views/filters/RecordSet-Filter-StringMatch.d.ts.map +1 -0
  90. package/types/views/filters/RecordSet-Filter-StringRange.d.ts +9 -0
  91. package/types/views/filters/RecordSet-Filter-StringRange.d.ts.map +1 -0
  92. package/types/views/filters/index.d.ts +20 -0
  93. package/types/views/filters/index.d.ts.map +1 -0
  94. package/types/views/list/RecordSet-List.d.ts +12 -2
  95. package/types/views/list/RecordSet-List.d.ts.map +1 -1
  96. package/source/views/RecordSet-Filter.js +0 -159
  97. package/types/views/RecordSet-Filter.d.ts +0 -39
  98. package/types/views/RecordSet-Filter.d.ts.map +0 -1
@@ -1,18 +1,18 @@
1
1
  const libFableServiceProviderBase = require('fable-serviceproviderbase');
2
2
 
3
- const viewDefinitionRecordSetErrorNotFound = require('../views/error/RecordSet-Error-NotFound.json');
4
- const viewRecordSetList = require('../views/list/RecordSet-List.js');
5
- const viewRecordSetEdit = require('../views/edit/RecordSet-Edit.js');
6
- const viewRecordSetRead = require('../views/read/RecordSet-Read.js');
7
- const viewRecordSetDashboard = require('../views/dashboard/RecordSet-Dashboard.js');
3
+ const ViewDefinitionRecordSetErrorNotFound = require('../views/error/RecordSet-Error-NotFound.json');
4
+ const ViewRecordSetList = require('../views/list/RecordSet-List.js');
5
+ const ViewRecordSetEdit = require('../views/edit/RecordSet-Edit.js');
6
+ const ViewRecordSetRead = require('../views/read/RecordSet-Read.js');
7
+ const ViewRecordSetDashboard = require('../views/dashboard/RecordSet-Dashboard.js');
8
8
 
9
9
  //_Pict.addProvider('BooksProvider', { Entity: 'Book', URLPrefix: 'http://www.datadebase.com:8086/1.0/' }, require('../source/providers/RecordSet-RecordProvider-MeadowEndpoints.js'));
10
- const providerBase = require('../providers/RecordSet-RecordProvider-Base.js');
11
- const providerMeadowEndpoints = require('../providers/RecordSet-RecordProvider-MeadowEndpoints.js');
10
+ const ProviderBase = require('../providers/RecordSet-RecordProvider-Base.js');
11
+ const ProviderMeadowEndpoints = require('../providers/RecordSet-RecordProvider-MeadowEndpoints.js');
12
12
 
13
- const providerLinkManager = require('../providers/RecordSet-Link-Manager.js');
13
+ const ProviderLinkManager = require('../providers/RecordSet-Link-Manager.js');
14
14
 
15
- const providerRouter = require('../providers/RecordSet-Router.js');
15
+ const ProviderRouter = require('../providers/RecordSet-Router.js');
16
16
 
17
17
  /** @type {Record<string, any>} */
18
18
  const _DEFAULT_CONFIGURATION =
@@ -20,6 +20,8 @@ const _DEFAULT_CONFIGURATION =
20
20
  DefaultMeadowURLPrefix: '/1.0/'
21
21
  };
22
22
 
23
+ const libFormsTemplateProvider = require('pict-section-form').PictFormTemplateProvider;
24
+
23
25
  class RecordSetMetacontroller extends libFableServiceProviderBase
24
26
  {
25
27
  constructor(pFable, pOptions, pServiceHash)
@@ -61,6 +63,9 @@ class RecordSetMetacontroller extends libFableServiceProviderBase
61
63
  this.manifests = { Default: this.pict.manifest };
62
64
 
63
65
  this.has_initialized = false;
66
+
67
+ //FIXME: this duplicates a behavior in pict-section-form - figure out how we want this coupled dependency to work.
68
+ this.fable.addProviderSingleton('PictFormSectionDefaultTemplateProvider', libFormsTemplateProvider.default_configuration, libFormsTemplateProvider);
64
69
  }
65
70
 
66
71
  /*
@@ -163,7 +168,7 @@ class RecordSetMetacontroller extends libFableServiceProviderBase
163
168
  {
164
169
  providerConfiguration.URLPrefix = '/1.0/';
165
170
  }
166
- tmpProvider = this.recordSetProviders[pRecordSetConfiguration.RecordSet] = this.fable.addProvider(providerConfiguration.Hash, providerConfiguration, providerMeadowEndpoints);
171
+ tmpProvider = this.recordSetProviders[pRecordSetConfiguration.RecordSet] = this.fable.addProvider(providerConfiguration.Hash, providerConfiguration, ProviderMeadowEndpoints);
167
172
  break;
168
173
  default:
169
174
  case 'Custom':
@@ -177,12 +182,12 @@ class RecordSetMetacontroller extends libFableServiceProviderBase
177
182
  }
178
183
  else
179
184
  {
180
- tmpProvider = this.recordSetProviders[providerConfiguration.RecordSet] = this.fable.addProvider(providerConfiguration.Hash, providerConfiguration, providerBase);
185
+ tmpProvider = this.recordSetProviders[providerConfiguration.RecordSet] = this.fable.addProvider(providerConfiguration.Hash, providerConfiguration, ProviderBase);
181
186
  }
182
187
  }
183
188
  else
184
189
  {
185
- tmpProvider = this.recordSetProviders[providerConfiguration.RecordSet] = this.fable.addProvider(providerConfiguration.Hash, providerConfiguration, providerBase);
190
+ tmpProvider = this.recordSetProviders[providerConfiguration.RecordSet] = this.fable.addProvider(providerConfiguration.Hash, providerConfiguration, ProviderBase);
186
191
  }
187
192
  break;
188
193
  }
@@ -302,15 +307,16 @@ class RecordSetMetacontroller extends libFableServiceProviderBase
302
307
  return this;
303
308
  }
304
309
 
305
- this.fable.addProvider('RecordSetLinkManager', {}, providerLinkManager);
310
+ this.fable.addProvider('RecordSetLinkManager', {}, ProviderLinkManager);
306
311
 
307
312
  // Add the subviews internally and externally
308
313
  this.pict.addTemplate(require('../templates/Pict-Template-FilterView.js'));
309
- this.childViews.errorNotFound = this.fable.addView('RSP-RecordSet-Error-NotFound', viewDefinitionRecordSetErrorNotFound);
310
- this.childViews.list = this.fable.addView('RSP-RecordSet-List', this.options, viewRecordSetList);
311
- this.childViews.edit = this.fable.addView('RSP-RecordSet-Edit', this.options, viewRecordSetEdit);
312
- this.childViews.read = this.fable.addView('RSP-RecordSet-Read', this.options, viewRecordSetRead);
313
- this.childViews.dashboard = this.fable.addView('RSP-RecordSet-Dashboard', this.options, viewRecordSetDashboard);
314
+ this.pict.addTemplate(require('../templates/Pict-Template-FilterInstanceViews.js'));
315
+ this.childViews.errorNotFound = this.fable.addView('RSP-RecordSet-Error-NotFound', ViewDefinitionRecordSetErrorNotFound);
316
+ this.childViews.list = this.fable.addView('RSP-RecordSet-List', this.options, ViewRecordSetList);
317
+ this.childViews.edit = this.fable.addView('RSP-RecordSet-Edit', this.options, ViewRecordSetEdit);
318
+ this.childViews.read = this.fable.addView('RSP-RecordSet-Read', this.options, ViewRecordSetRead);
319
+ this.childViews.dashboard = this.fable.addView('RSP-RecordSet-Dashboard', this.options, ViewRecordSetDashboard);
314
320
 
315
321
  // Initialize the subviews
316
322
  this.childViews.list.initialize();
@@ -320,6 +326,22 @@ class RecordSetMetacontroller extends libFableServiceProviderBase
320
326
 
321
327
  // Now initialize the router
322
328
 
329
+ if (this.fable.settings.hasOwnProperty('Filters') && typeof this.fable.settings.Filters === 'object')
330
+ {
331
+ for (const tmpFilterKey of Object.keys(this.fable.settings.Filters))
332
+ {
333
+ this.pict.providers.FilterManager.addFilter(tmpFilterKey, this.fable.settings.Filters[tmpFilterKey]);
334
+ }
335
+ }
336
+
337
+ if (this.fable.settings.hasOwnProperty('FilterCriteria') && typeof this.fable.settings.FilterCriteria === 'object')
338
+ {
339
+ for (const tmpFilterCriterionKey of Object.keys(this.fable.settings.FilterCriteria))
340
+ {
341
+ this.pict.providers.FilterManager.addFilterCriteria(tmpFilterCriterionKey, this.fable.settings.FilterCriteria[tmpFilterCriterionKey]);
342
+ }
343
+ }
344
+
323
345
  if (this.fable.settings.hasOwnProperty('DefaultRecordSetConfigurations'))
324
346
  {
325
347
  this.loadRecordSetConfigurationArray(this.fable.settings.DefaultRecordSetConfigurations);
@@ -346,7 +368,7 @@ class RecordSetMetacontroller extends libFableServiceProviderBase
346
368
  // Load pict-router if it isn't loaded
347
369
  if (!('RecordSetRouter' in this.fable.providers))
348
370
  {
349
- this.fable.addProvider('RecordSetRouter', {}, providerRouter);
371
+ this.fable.addProvider('RecordSetRouter', {}, ProviderRouter);
350
372
  this.fable.providers.RecordSetRouter.initialize();
351
373
  }
352
374
 
@@ -0,0 +1,222 @@
1
+ const libPictTemplate = require('pict-template');
2
+ const libFilterViews = require('../views/filters/index.js');
3
+
4
+ /**
5
+ * Specialized instruction for rendering the filter view and plumbing in required context.
6
+ *
7
+ * Based on the Pict base {~V:...~} template instruction.
8
+ */
9
+ class PictTemplateFilterInstanceViewInstruction extends libPictTemplate
10
+ {
11
+ /**
12
+ * @param {Object} pFable - The Fable Framework instance
13
+ * @param {Object} pOptions - The options for the service
14
+ * @param {String} pServiceHash - The hash of the service
15
+ */
16
+ constructor(pFable, pOptions, pServiceHash)
17
+ {
18
+ super(pFable, pOptions, pServiceHash);
19
+
20
+ /** @type {any} */
21
+ this.log;
22
+
23
+ this.addPattern('{~FIV:', '~}');
24
+ this.addPattern('{~FilterInstanceViews:', '~}');
25
+
26
+
27
+ if (!('__TemplateOutputCache' in this.pict))
28
+ {
29
+ this.pict.__TemplateOutputCache = {};
30
+ }
31
+ }
32
+
33
+ _getViewForFilterClauses(pClauses)
34
+ {
35
+ const tmpViewHash =`PSRS-FilterType-${pClauses.Type}`;
36
+ /** @type {import('../views/filters/RecordSet-Filter-Base.js')} */
37
+ let tmpView = this.pict.views[tmpViewHash];
38
+ if (!tmpView)
39
+ {
40
+ const tmpViewPrototype = libFilterViews[pClauses.Type] || libFilterViews.Base;
41
+ if (!tmpViewPrototype)
42
+ {
43
+ this.pict.log.error(`Pict: Filter Instance Views Template Render: No view prototype found for filter type [${pClauses.Type}]`);
44
+ return null;
45
+ }
46
+ //FIXME: is this safe? will this view get rendered at other times?
47
+ tmpView = this.pict.addView(tmpViewHash, { }, tmpViewPrototype);
48
+ }
49
+ return tmpView;
50
+ }
51
+
52
+ /**
53
+ * Render a template expression, returning a string with the resulting content.
54
+ *
55
+ * @param {string} pTemplateHash - The hash contents of the template (what's between the template start and stop tags)
56
+ * @param {any} pRecord - The json object to be used as the Record for the template render
57
+ * @param {Array<any>} pContextArray - An array of context objects accessible from the template; safe to leave empty
58
+ * @param {any} [pScope] - A sticky scope that can be used to carry state and simplify template
59
+ *
60
+ * @return {string} The rendered template
61
+ */
62
+ render(pTemplateHash, pRecord, pContextArray, pScope)
63
+ {
64
+ const tmpRecordSet = pRecord.RecordSet || '';
65
+ if (!tmpRecordSet)
66
+ {
67
+ this.pict.log.error(`Pict: Filter Instance Views Template Render: No record set specified in record`);
68
+ return '';
69
+ }
70
+ const tmpRecordSetConfiguration = this.pict.PictSectionRecordSet.recordSetProviderConfigurations?.[tmpRecordSet];
71
+ if (!tmpRecordSetConfiguration)
72
+ {
73
+ this.pict.log.error(`Pict: Filter Instance Views Template Render: No record set configuration found for [${tmpRecordSet}]`);
74
+ return '';
75
+ }
76
+ let tmpViewContext = pRecord.ViewContext;
77
+ if (tmpViewContext)
78
+ {
79
+ tmpViewContext = tmpViewContext.trim();
80
+ }
81
+ else
82
+ {
83
+ tmpViewContext = 'Default';
84
+ }
85
+ pRecord = pRecord || {};
86
+ if (!pRecord.RecordSet)
87
+ {
88
+ pRecord.RecordSet = tmpRecordSet;
89
+ }
90
+ if (!pRecord.RecordSetConfiguration)
91
+ {
92
+ pRecord.RecordSetConfiguration = tmpRecordSetConfiguration;
93
+ }
94
+ if (!pRecord.ViewContext)
95
+ {
96
+ pRecord.ViewContext = pRecord.DashboardHash ? `${tmpViewContext}-${pRecord.DashboardHash}` : tmpViewContext;
97
+ }
98
+
99
+ let tmpRenderGUID = this.pict.getUUID();
100
+ let tmpResult = '';
101
+
102
+ const tmpClauses = this.pict.Bundle._ActiveFilterState?.[pRecord.RecordSet]?.FilterClauses || [];
103
+ //FIXME: lookup by hash instead?
104
+ for (let i = 0; i < tmpClauses.length; i++)
105
+ //for (const tmpClauses of this.pict.Bundle._ActiveFilterState?.[pRecord.RecordSet]?.FilterClauses || [])
106
+ {
107
+ const tmpClause = tmpClauses[i];
108
+ /** @type {import('../views/filters/RecordSet-Filter-Base.js')} */
109
+ const tmpView = this._getViewForFilterClauses(tmpClause);
110
+ if (!tmpView)
111
+ {
112
+ continue;
113
+ }
114
+
115
+ const tmpRecord = Object.assign({}, pRecord, tmpClause);
116
+ //tmpRecord.ClauseAddress = `Bundle._ActiveFilterState['${pRecord.RecordSet}'].FilterClauses[${i}]`;
117
+ tmpRecord.ClauseAddress = `_ActiveFilterState[\`${pRecord.RecordSet}\`].FilterClauses[${i}]`;
118
+ tmpView.prepareRecord(tmpRecord);
119
+ tmpView.renderWithScope(tmpClause, '__Virtual', `__TemplateOutputCache.${tmpRenderGUID}`, tmpRecord);
120
+
121
+ tmpResult += this.pict.__TemplateOutputCache[tmpRenderGUID];
122
+ // TODO: Uncomment this when we like how it's working
123
+ //delete this.pict.__TemplateOutputCache[tmpRenderGUID];
124
+
125
+ }
126
+ return tmpResult;
127
+ }
128
+
129
+ /**
130
+ * @param {string} pTemplateHash - The hash contents of the template (what's between the template start and stop tags)
131
+ * @param {any} pRecord - The json object to be used as the Record for the template
132
+ * @param {(pError?: Error, pResult?: string) => void} fCallback - The callback function to call with the result
133
+ * @param {Array<any>} pContextArray - An array of context objects accessible from the template; safe to leave empty
134
+ * @param {any} [pScope] - A sticky scope that can be used to carry state and simplify template
135
+ * @return {void}
136
+ */
137
+ renderAsync(pTemplateHash, pRecord, fCallback, pContextArray, pScope)
138
+ {
139
+ const tmpRecordSet = pRecord.RecordSet || '';
140
+ if (!tmpRecordSet)
141
+ {
142
+ this.pict.log.error(`Pict: Filter Instance Views Template Render: No record set specified in record`);
143
+ return fCallback(null, '');
144
+ }
145
+ const tmpRecordSetConfiguration = this.pict.PictSectionRecordSet.recordSetProviderConfigurations?.[tmpRecordSet];
146
+ if (!tmpRecordSetConfiguration)
147
+ {
148
+ this.pict.log.error(`Pict: Filter Instance Views Template Render: No record set configuration found for [${tmpRecordSet}]`);
149
+ return fCallback(null, '');
150
+ }
151
+ let tmpViewContext = pRecord.ViewContext;
152
+ if (tmpViewContext)
153
+ {
154
+ tmpViewContext = tmpViewContext.trim();
155
+ }
156
+ else
157
+ {
158
+ tmpViewContext = 'Default';
159
+ }
160
+
161
+ pRecord = pRecord || {};
162
+ if (!pRecord.RecordSet)
163
+ {
164
+ pRecord.RecordSet = tmpRecordSet;
165
+ }
166
+ if (!pRecord.RecordSetConfiguration)
167
+ {
168
+ pRecord.RecordSetConfiguration = tmpRecordSetConfiguration;
169
+ }
170
+ if (!pRecord.ViewContext)
171
+ {
172
+ pRecord.ViewContext = pRecord.DashboardHash ? `${tmpViewContext}-${pRecord.DashboardHash}` : tmpViewContext;
173
+ }
174
+ const tmpAnticipate = this.pict.newAnticipate();
175
+ let tmpResult = '';
176
+
177
+ const tmpClauses = this.pict.Bundle._ActiveFilterState?.[pRecord.RecordSet]?.FilterClauses || [];
178
+ //FIXME: lookup by hash instead?
179
+ for (let i = 0; i < tmpClauses.length; i++)
180
+ {
181
+ const tmpClause = tmpClauses[i];
182
+ /** @type {import('../views/filters/RecordSet-Filter-Base.js')} */
183
+ const tmpView = this._getViewForFilterClauses(tmpClause);
184
+ if (!tmpView)
185
+ {
186
+ continue;
187
+ }
188
+
189
+ const tmpRenderGUID = this.pict.getUUID();
190
+ tmpAnticipate.anticipate((fNext) =>
191
+ {
192
+ const tmpRecord = Object.assign({}, pRecord, tmpClause);
193
+ tmpRecord.ClauseAddress = `_ActiveFilterState[${pRecord.RecordSet}].FilterClauses[${i}]`;
194
+ tmpView.prepareRecord(tmpRecord);
195
+
196
+ return tmpView.renderWithScopeAsync(tmpClause, '__Virtual', `__TemplateOutputCache.${tmpRenderGUID}`, tmpRecord,
197
+ (pError, pResult) =>
198
+ {
199
+ if (pError)
200
+ {
201
+ this.log.warn(`Pict: Filter Instance Views Template Render: Error rendering view [${tmpView.Hash}]`, pError);
202
+ //TODO: should we fail the whole render?
203
+ return fNext();
204
+ //return fNext(pError);
205
+ }
206
+
207
+ tmpResult += this.pict.__TemplateOutputCache[tmpRenderGUID];
208
+ // TODO: Uncomment this when we like how it's working
209
+ //delete this.pict.__TemplateOutputCache[tmpRenderGUID];
210
+
211
+ return fNext(null);
212
+ });
213
+ });
214
+ }
215
+ return tmpAnticipate.wait((pError) =>
216
+ {
217
+ return fCallback(pError, tmpResult);
218
+ });
219
+ }
220
+ }
221
+
222
+ module.exports = PictTemplateFilterInstanceViewInstruction;
@@ -35,10 +35,11 @@ class PictTemplateFilterViewInstruction extends libPictTemplate
35
35
  * @param {string} pTemplateHash - The hash contents of the template (what's between the template start and stop tags)
36
36
  * @param {any} pRecord - The json object to be used as the Record for the template render
37
37
  * @param {Array<any>} pContextArray - An array of context objects accessible from the template; safe to leave empty
38
+ * @param {any} [pScope] - A sticky scope that can be used to carry state and simplify template
38
39
  *
39
40
  * @return {string} The rendered template
40
41
  */
41
- render(pTemplateHash, pRecord, pContextArray)
42
+ render(pTemplateHash, pRecord, pContextArray, pScope)
42
43
  {
43
44
  let [ tmpViewHash, tmpViewContext ] = pTemplateHash.split(':');
44
45
  tmpViewHash = tmpViewHash.trim();
@@ -101,9 +102,10 @@ class PictTemplateFilterViewInstruction extends libPictTemplate
101
102
  * @param {any} pRecord - The json object to be used as the Record for the template
102
103
  * @param {(pError?: Error, pResult?: string) => void} fCallback - The callback function to call with the result
103
104
  * @param {Array<any>} pContextArray - An array of context objects accessible from the template; safe to leave empty
105
+ * @param {any} [pScope] - A sticky scope that can be used to carry state and simplify template
104
106
  * @return {void}
105
107
  */
106
- renderAsync(pTemplateHash, pRecord, fCallback, pContextArray)
108
+ renderAsync(pTemplateHash, pRecord, fCallback, pContextArray, pScope)
107
109
  {
108
110
  let [ tmpViewHash, tmpViewContext ] = pTemplateHash.split(':');
109
111
  tmpViewHash = tmpViewHash.trim();