pict-section-recordset 1.0.24 → 1.0.27

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 +172 -111
  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,7 +1,10 @@
1
1
  const libPictRecordSet = require('../../source/Pict-Section-RecordSet.js');
2
- //const libPictSectionForm = require('pict-section-recordset');
3
2
 
4
- module.exports = libPictRecordSet.PictRecordSetApplication;
3
+ class SimpleApplication extends libPictRecordSet.PictRecordSetApplication
4
+ {
5
+ }
6
+
7
+ module.exports = SimpleApplication;
5
8
 
6
9
  module.exports.default_configuration.pict_configuration = (
7
10
  {
@@ -175,133 +178,191 @@ module.exports.default_configuration.pict_configuration = (
175
178
  },
176
179
  }
177
180
  },
178
- "DefaultRecordSetConfigurations":
181
+ "Filters":
182
+ {
183
+ "ExternalJoinBookByAuthor":
184
+ {
185
+ "Type": "ExternalJoinStringMatch",
186
+ "ExternalFilterByColumns": [ "Name" ],
187
+
188
+ "CoreConnectionColumn": "IDBook",
189
+
190
+ "JoinTable": "BookAuthorJoin",
191
+ "JoinTableExternalConnectionColumn": "IDAuthor",
192
+ "JoinTableCoreConnectionColumn": "IDBook",
193
+
194
+ "ExternalFilterByTable": "Author",
195
+ "ExternalFilterByTableConnectionColumn": "IDAuthor"
196
+ }
197
+ },
198
+ "FilterCriteria":
199
+ {
200
+ "FilterRecordsetByBookAndCreateDate":
179
201
  [
180
202
  {
181
- "RecordSet": "Book",
203
+ "FilterDefinitionHash": "ExternalJoinBookByAuthor",
204
+ "FilterByColumn": "IDBook"
205
+ },
206
+ {
207
+ "Type": "DateRange",
208
+ "FilterByColumn": "CreateDate"
209
+ },
210
+ {
211
+ "Type": "StringMatch",
212
+ "FilterByColumn": "Genre"
213
+ }
214
+ ],
215
+ "FilterRecordsetByTitle":
216
+ [
217
+ {
218
+ "Type": "StringMatch",
219
+ "FilterByColumn": "Title"
220
+ },
221
+ ]
222
+ },
182
223
 
183
- "RecordSetType": "MeadowEndpoint", // Could be "Custom" which would require a provider to already be created for the record set.
184
- "RecordSetMeadowEntity": "Book", // This leverages the /Schema endpoint to get the record set columns.
224
+ "DefaultRecordSetConfigurations":
225
+ [
226
+ {
227
+ "RecordSet": "Book",
185
228
 
186
- "RecordSetListColumns": [
187
- {
188
- "Key": "Title",
189
- "DisplayName": "Title"
190
- },
191
- {
192
- "Key": "Genre",
193
- "DisplayName": "Genre"
194
- },
195
- {
196
- "Key": "ISBN",
197
- "DisplayName": "Int'l SBN"
198
- }
199
- ],
229
+ "RecordSetType": "MeadowEndpoint", // Could be "Custom" which would require a provider to already be created for the record set.
230
+ "RecordSetMeadowEntity": "Book", // This leverages the /Schema endpoint to get the record set columns.
231
+
232
+ "RecordSetListColumns": [
233
+ {
234
+ "Key": "Title",
235
+ "DisplayName": "Title"
236
+ },
237
+ {
238
+ "Key": "Genre",
239
+ "DisplayName": "Genre"
240
+ },
241
+ {
242
+ "Key": "ISBN",
243
+ "DisplayName": "Int'l SBN"
244
+ }
245
+ ],
246
+
247
+ "FilterExperiences":
248
+ {
249
+ "FilterByAuthorAndCreateDate":
250
+ {
251
+ "Ordinal": 1,
252
+ "FilterCriteriaHash": "FilterRecordsetByBookAndCreateDate",
253
+ "Default": true
254
+ },
255
+ "FilterByTitle":
256
+ {
257
+ "Ordinal": 2,
258
+ "FilterCriteriaHash": "FilterRecordsetByTitle"
259
+ }
260
+ },
200
261
 
201
- "RecordSetListManifestOnly": false,
262
+ "RecordSetListManifestOnly": false,
202
263
 
203
- "RecordSetListManifests": [ "Bestsellers", "Underdogs", "NewReleases" ],
204
- "RecordSetDashboardManifests": [ "Bestsellers" ],
264
+ "RecordSetListManifests": [ "Bestsellers", "Underdogs", "NewReleases" ],
265
+ "RecordSetDashboardManifests": [ "Bestsellers" ],
205
266
 
206
- "RecordSetListHasExtraColumns": true,
207
- "RecordSetListExtraColumnsHeaderTemplate": "<th style=\"border-bottom: 1px solid #ccc; padding: 5px; background-color: #f2f2f2; color: #333;\">Cover</th>",
208
- "RecordSetListExtraColumnRowTemplate": "<td><img src=\"{~D:Record.Data.ImageURL~}\"></td>",
267
+ "RecordSetListHasExtraColumns": true,
268
+ "RecordSetListExtraColumnsHeaderTemplate": "<th style=\"border-bottom: 1px solid #ccc; padding: 5px; background-color: #f2f2f2; color: #333;\">Cover</th>",
269
+ "RecordSetListExtraColumnRowTemplate": "<td><img src=\"{~D:Record.Data.ImageURL~}\"></td>",
209
270
 
210
- "SearchFields": [ "Title" ],
271
+ "SearchFields": [ "Title" ],
211
272
 
212
- "RecordSetFilterURLTemplate-Default": "/PSRS/{~D:Record.RecordSet~}/List/FilteredTo/{~D:Record.FilterString~}",
213
- "RecordSetFilterURLTemplate-List": "/PSRS/{~D:Record.RecordSet~}/List/FilteredTo/{~D:Record.FilterString~}",
214
- "RecordSetFilterURLTemplate-Dashboard": "/PSRS/{~D:Record.RecordSet~}/Dashboard/FilteredTo/{~D:Record.FilterString~}",
273
+ "RecordSetFilterURLTemplate-Default": "/PSRS/{~D:Record.RecordSet~}/List/FilteredTo/{~D:Record.FilterString~}",
274
+ "RecordSetFilterURLTemplate-List": "/PSRS/{~D:Record.RecordSet~}/List/FilteredTo/{~D:Record.FilterString~}",
275
+ "RecordSetFilterURLTemplate-Dashboard": "/PSRS/{~D:Record.RecordSet~}/Dashboard/FilteredTo/{~D:Record.FilterString~}",
215
276
 
216
- "RecordSetURLPrefix": "/1.0/"
217
- },
218
- {
219
- "RecordSet": "BookstoreInventory",
220
- "Title": "Bookstore Inventory",
277
+ "RecordSetURLPrefix": "/1.0/"
278
+ },
279
+ {
280
+ "RecordSet": "BookstoreInventory",
281
+ "Title": "Bookstore Inventory",
221
282
 
222
- "RecordSetType": "MeadowEndpoint", // Could be "Custom" which would require a provider to already be created for the record set.
223
- "RecordSetMeadowEntity": "Book", // This leverages the /Schema endpoint to get the record set columns.
283
+ "RecordSetType": "MeadowEndpoint", // Could be "Custom" which would require a provider to already be created for the record set.
284
+ "RecordSetMeadowEntity": "Book", // This leverages the /Schema endpoint to get the record set columns.
224
285
 
225
- "RecordSetListManifestOnly": true,
286
+ "RecordSetListManifestOnly": true,
226
287
 
227
- "RecordSetDashboardManifests": [ "Bestsellers", "Underdogs", "NewReleases" ],
288
+ "RecordSetDashboardManifests": [ "Bestsellers", "Underdogs", "NewReleases" ],
228
289
 
229
- "RecordDecorationConfiguration":
230
- [
231
- {
232
- "Entity": "BookAuthorJoin",
233
- "Filter": "FBL~IDBook~INN~{~PJU:,^IDBook^Record.State.CoreEntityRecordSubset~}",
234
- "Destination": "State.BookAuthorJoins"
235
- },
236
- {
237
- "Entity": "Author",
238
- "Filter": "FBL~IDAuthor~INN~{~PJU:,^IDAuthor^Record.State.BookAuthorJoins~}",
239
- "Destination": "State.Authors"
240
- },
241
- {
242
- "Type": "MapJoin",
243
- "DestinationRecordSetAddress": "State.CoreEntityRecordSubset",
244
- "DestinationJoinValue": "IDBook",
245
- "JoinJoinValueLHS": "IDBook",
246
- "Joins": "State.BookAuthorJoins",
247
- "JoinJoinValueRHS": "IDAuthor",
248
- "JoinRecordSetAddress": "State.Authors",
249
- "JoinValue": "IDAuthor",
250
- "RecordDestinationAddress": "Authors"
251
- },
252
- {
253
- "Entity": "BookAuthorJoin",
254
- "Filter": "FBL~IDAuthor~INN~{~PJU:,^IDAuthor^Record.State.Authors~}",
255
- "Destination": "State.BookAuthorJoinsRev"
256
- },
257
- {
258
- "Entity": "Book",
259
- "Filter": "FBL~IDBook~INN~{~PJU:,^IDBook^Record.State.BookAuthorJoinsRev~}",
260
- "Destination": "State.BooksForAuthors"
261
- },
262
- {
263
- "Type": "MapJoin",
264
- "DestinationRecordSetAddress": "State.Authors",
265
- "DestinationJoinValue": "IDAuthor",
266
- "JoinJoinValueLHS": "IDAuthor",
267
- "Joins": "State.BookAuthorJoinsRev",
268
- "JoinJoinValueRHS": "IDBook",
269
- "JoinRecordSetAddress": "State.BooksForAuthors",
270
- "JoinValue": "IDBook",
271
- "RecordDestinationAddress": "Books"
272
- }
273
- ],
274
- "AvailableVerbs": [ "Dashboard" ],
290
+ "RecordDecorationConfiguration":
291
+ [
292
+ {
293
+ "Entity": "BookAuthorJoin",
294
+ "Filter": "FBL~IDBook~INN~{~PJU:,^IDBook^Record.State.CoreEntityRecordSubset~}",
295
+ "Destination": "State.BookAuthorJoins"
296
+ },
297
+ {
298
+ "Entity": "Author",
299
+ "Filter": "FBL~IDAuthor~INN~{~PJU:,^IDAuthor^Record.State.BookAuthorJoins~}",
300
+ "Destination": "State.Authors"
301
+ },
302
+ {
303
+ "Type": "MapJoin",
304
+ "DestinationRecordSetAddress": "State.CoreEntityRecordSubset",
305
+ "DestinationJoinValue": "IDBook",
306
+ "JoinJoinValueLHS": "IDBook",
307
+ "Joins": "State.BookAuthorJoins",
308
+ "JoinJoinValueRHS": "IDAuthor",
309
+ "JoinRecordSetAddress": "State.Authors",
310
+ "JoinValue": "IDAuthor",
311
+ "RecordDestinationAddress": "Authors"
312
+ },
313
+ {
314
+ "Entity": "BookAuthorJoin",
315
+ "Filter": "FBL~IDAuthor~INN~{~PJU:,^IDAuthor^Record.State.Authors~}",
316
+ "Destination": "State.BookAuthorJoinsRev"
317
+ },
318
+ {
319
+ "Entity": "Book",
320
+ "Filter": "FBL~IDBook~INN~{~PJU:,^IDBook^Record.State.BookAuthorJoinsRev~}",
321
+ "Destination": "State.BooksForAuthors"
322
+ },
323
+ {
324
+ "Type": "MapJoin",
325
+ "DestinationRecordSetAddress": "State.Authors",
326
+ "DestinationJoinValue": "IDAuthor",
327
+ "JoinJoinValueLHS": "IDAuthor",
328
+ "Joins": "State.BookAuthorJoinsRev",
329
+ "JoinJoinValueRHS": "IDBook",
330
+ "JoinRecordSetAddress": "State.BooksForAuthors",
331
+ "JoinValue": "IDBook",
332
+ "RecordDestinationAddress": "Books"
333
+ }
334
+ ],
335
+ "AvailableVerbs": [ "Dashboard" ],
275
336
 
276
- "RecordSetListHasExtraColumns": true,
277
- "RecordSetListExtraColumnsHeaderTemplate": "<th style=\"border-bottom: 1px solid #ccc; padding: 5px; background-color: #f2f2f2; color: #333;\">Cover</th>",
278
- "RecordSetListExtraColumnRowTemplate": "<td><img src=\"{~D:Record.Data.ImageURL~}\"></td>",
337
+ "RecordSetListHasExtraColumns": true,
338
+ "RecordSetListExtraColumnsHeaderTemplate": "<th style=\"border-bottom: 1px solid #ccc; padding: 5px; background-color: #f2f2f2; color: #333;\">Cover</th>",
339
+ "RecordSetListExtraColumnRowTemplate": "<td><img src=\"{~D:Record.Data.ImageURL~}\"></td>",
279
340
 
280
- "SearchFields": [ "Title" ],
341
+ "SearchFields": [ "Title" ],
281
342
 
282
- "RecordSetFilterURLTemplate-Default": "/PSRS/{~D:Record.RecordSet~}/List/FilteredTo/{~D:Record.FilterString~}",
283
- "RecordSetFilterURLTemplate-List": "/PSRS/{~D:Record.RecordSet~}/List/FilteredTo/{~D:Record.FilterString~}",
284
- "RecordSetFilterURLTemplate-Dashboard": "/PSRS/{~D:Record.RecordSet~}/Dashboard/FilteredTo/{~D:Record.FilterString~}",
285
- //TODO: something like this to reduce boilerplate
286
- "RecordSetFilterURLTemplate-Dashboard-Specific": "/PSRS/{~D:Record.RecordSet~}/SpecificDashboard/$$DASHBOARD_HASH$$/FilteredTo/{~D:Record.FilterString~}",
287
- "RecordSetFilterURLTemplate-Dashboard-Bestsellers": "/PSRS/{~D:Record.RecordSet~}/SpecificDashboard/Bestsellers/FilteredTo/{~D:Record.FilterString~}",
288
- "RecordSetFilterURLTemplate-Dashboard-Underdogs": "/PSRS/{~D:Record.RecordSet~}/SpecificDashboard/Underdogs/FilteredTo/{~D:Record.FilterString~}",
289
- "RecordSetFilterURLTemplate-Dashboard-NewReleases": "/PSRS/{~D:Record.RecordSet~}/SpecificDashboard/NewReleases/FilteredTo/{~D:Record.FilterString~}",
343
+ "RecordSetFilterURLTemplate-Default": "/PSRS/{~D:Record.RecordSet~}/List/FilteredTo/{~D:Record.FilterString~}",
344
+ "RecordSetFilterURLTemplate-List": "/PSRS/{~D:Record.RecordSet~}/List/FilteredTo/{~D:Record.FilterString~}",
345
+ "RecordSetFilterURLTemplate-Dashboard": "/PSRS/{~D:Record.RecordSet~}/Dashboard/FilteredTo/{~D:Record.FilterString~}",
346
+ //TODO: something like this to reduce boilerplate
347
+ "RecordSetFilterURLTemplate-Dashboard-Specific": "/PSRS/{~D:Record.RecordSet~}/SpecificDashboard/$$DASHBOARD_HASH$$/FilteredTo/{~D:Record.FilterString~}",
348
+ "RecordSetFilterURLTemplate-Dashboard-Bestsellers": "/PSRS/{~D:Record.RecordSet~}/SpecificDashboard/Bestsellers/FilteredTo/{~D:Record.FilterString~}",
349
+ "RecordSetFilterURLTemplate-Dashboard-Underdogs": "/PSRS/{~D:Record.RecordSet~}/SpecificDashboard/Underdogs/FilteredTo/{~D:Record.FilterString~}",
350
+ "RecordSetFilterURLTemplate-Dashboard-NewReleases": "/PSRS/{~D:Record.RecordSet~}/SpecificDashboard/NewReleases/FilteredTo/{~D:Record.FilterString~}",
290
351
 
291
- "RecordSetURLPrefix": "/1.0/"
292
- },
293
- {
294
- "RecordSet": "Author",
352
+ "RecordSetURLPrefix": "/1.0/"
353
+ },
354
+ {
355
+ "RecordSet": "Author",
295
356
 
296
- "RecordSetType": "MeadowEndpoint",
297
- "RecordSetMeadowEntity": "Author",
357
+ "RecordSetType": "MeadowEndpoint",
358
+ "RecordSetMeadowEntity": "Author",
298
359
 
299
- "RecordSetURLPrefix": "/1.0/"
300
- },
301
- {
302
- "RecordSet": "RandomizedValues",
360
+ "RecordSetURLPrefix": "/1.0/"
361
+ },
362
+ {
363
+ "RecordSet": "RandomizedValues",
303
364
 
304
- "RecordSetType": "Custom" // This means the `PS-RSP-RandomizedValues` provider will be checked for to get records.
305
- }
306
- ]
307
- });
365
+ "RecordSetType": "Custom" // This means the `PS-RSP-RandomizedValues` provider will be checked for to get records.
366
+ }
367
+ ]
368
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pict-section-recordset",
3
- "version": "1.0.24",
3
+ "version": "1.0.27",
4
4
  "description": "Pict dynamic record set management views",
5
5
  "main": "source/Pict-Section-RecordSet.js",
6
6
  "directories": {
@@ -20,7 +20,7 @@
20
20
  "coverage": "npx nyc --reporter=lcov --reporter=text-lcov npx mocha -- -u tdd -R spec",
21
21
  "build": "npx quack build",
22
22
  "test": "npx mocha -u tdd -R spec",
23
- "lint": "eslint source/**",
23
+ "lint": "eslint source",
24
24
  "types": "tsc -p tsconfig.build.json"
25
25
  },
26
26
  "types": "types/Pict-Section-RecordSet.d.ts",
@@ -33,19 +33,19 @@
33
33
  "browser-env": "^3.3.0",
34
34
  "eslint": "^9.28.0",
35
35
  "jquery": "^3.7.1",
36
- "pict": "^1.0.272",
36
+ "pict": "^1.0.288",
37
37
  "pict-application": "^1.0.27",
38
38
  "pict-service-commandlineutility": "^1.0.15",
39
- "quackage": "^1.0.41",
39
+ "quackage": "^1.0.42",
40
40
  "typescript": "^5.8.3"
41
41
  },
42
42
  "dependencies": {
43
43
  "fable-serviceproviderbase": "^3.0.15",
44
44
  "pict-provider": "^1.0.6",
45
45
  "pict-router": "^1.0.4",
46
- "pict-section-form": "^1.0.98",
47
- "pict-template": "^1.0.11",
48
- "pict-view": "^1.0.61"
46
+ "pict-section-form": "^1.0.106",
47
+ "pict-template": "^1.0.12",
48
+ "pict-view": "^1.0.62"
49
49
  },
50
50
  "mocha": {
51
51
  "diff": true,
@@ -1,7 +1,9 @@
1
1
  const libPictApplication = require('pict-application');
2
+ const libPictSectionForm = require('pict-section-form');
2
3
 
3
4
  const libPictSectionRecordSet = require('../Pict-Section-RecordSet.js');
4
5
  const libDynamicSolver = require('../providers/RecordSet-DynamicRecordsetSolver.js');
6
+ const libPictDynamicFormDependencyManager = require('pict-section-form').PictDynamicFormDependencyManager;
5
7
 
6
8
  /**
7
9
  * Represents a PictSectionRecordSetApplication.
@@ -21,7 +23,13 @@ class PictSectionRecordSetApplication extends libPictApplication
21
23
  this.pict;
22
24
  // Add the pict recordset meta controller service
23
25
  this.pict.addServiceType('PictSectionRecordSet', libPictSectionRecordSet);
26
+ //FIXME: this is probably wrong, but needed for now?
27
+ this.pict.addServiceType('PictSectionForm', libPictSectionForm);
28
+
24
29
  this.fable.addProviderSingleton('DynamicRecordsetSolver', libDynamicSolver.default_configuration, libDynamicSolver);
30
+
31
+ // add the dependencies for dynamic controls
32
+ this.fable.addAndInstantiateSingletonService('PictDynamicFormDependencyManager', libPictDynamicFormDependencyManager.default_configuration, libPictDynamicFormDependencyManager);
25
33
  }
26
34
 
27
35
  onInitialize()
@@ -9,7 +9,7 @@ const _DEFAULT_PROVIDER_CONFIGURATION =
9
9
  AutoInitializeOrdinal: 0
10
10
  }
11
11
 
12
- class PictRecordSetRouter extends libPictProvider
12
+ class PictRecordSetLinkManager extends libPictProvider
13
13
  {
14
14
  constructor(pFable, pOptions, pServiceHash)
15
15
  {
@@ -49,5 +49,5 @@ class PictRecordSetRouter extends libPictProvider
49
49
  }
50
50
  }
51
51
 
52
- module.exports = PictRecordSetRouter;
52
+ module.exports = PictRecordSetLinkManager;
53
53
  module.exports.default_configuration = _DEFAULT_PROVIDER_CONFIGURATION;
@@ -52,7 +52,7 @@ class RecordSetProviderBase extends libPictProvider
52
52
  {
53
53
  /**
54
54
  * Creates an instance of RecordSetProvider.
55
- * @param {import('fable')} pFable - The Fable object.
55
+ * @param {import('pict')} pFable - The Fable object.
56
56
  * @param {Record<string, any>} [pOptions] - Custom options for the provider.
57
57
  * @param {string} [pServiceHash] - The service hash.
58
58
  */
@@ -64,7 +64,7 @@ class RecordSetProviderBase extends libPictProvider
64
64
 
65
65
  /** @type {Record<string, any>} */
66
66
  this.options;
67
- /** @type {import('fable')} */
67
+ /** @type {import('pict')} */
68
68
  this.fable;
69
69
  /** @type {import('pict')} */
70
70
  this.pict;
@@ -92,6 +92,13 @@ class RecordSetProviderBase extends libPictProvider
92
92
  return { };
93
93
  }
94
94
 
95
+ /*
96
+ get availableFilters()
97
+ {
98
+ return { IDBook: [ 'NumericMatch', 'NumericRange', 'ExternalJoinBookByAuthor' ], Title: [ 'StringMatch', 'StringRange' ] };
99
+ }
100
+ */
101
+
95
102
  /**
96
103
  * Read records from the provider.
97
104
  *
@@ -14,7 +14,7 @@ class MeadowEndpointsRecordSetProvider extends libRecordSetProviderBase
14
14
  {
15
15
  /**
16
16
  * Creates an instance of RecordSetProvider.
17
- * @param {import('fable')} pFable - The Fable object.
17
+ * @param {import('pict')} pFable - The Fable object.
18
18
  * @param {Record<string, any>} [pOptions] - Custom options for the provider.
19
19
  * @param {string} [pServiceHash] - The service hash.
20
20
  */
@@ -24,8 +24,6 @@ class MeadowEndpointsRecordSetProvider extends libRecordSetProviderBase
24
24
 
25
25
  /** @type {Record<string, any>} */
26
26
  this.options;
27
- /** @type {import('fable')} */
28
- this.fable;
29
27
  /** @type {import('pict') & {
30
28
  * log: any,
31
29
  * services:
@@ -37,6 +35,7 @@ class MeadowEndpointsRecordSetProvider extends libRecordSetProviderBase
37
35
  * PictSectionRecordSet: InstanceType<import('../Pict-Section-RecordSet.js')>
38
36
  * }} */
39
37
  this.pict;
38
+ this.fable = this.pict;
40
39
  /** @type {string} */
41
40
  this.Hash;
42
41
  /** @type {string} */
@@ -44,6 +43,10 @@ class MeadowEndpointsRecordSetProvider extends libRecordSetProviderBase
44
43
  //TODO: make this typedef better
45
44
  /** @type {Record<string, any>} */
46
45
  this._Schema = { };
46
+ /** @type {Record<string, Record<string, any>>} */
47
+ this._Experiences = { };
48
+ /** @type {Record<string, Record<string, any>>} */
49
+ this._FiltersByField = { };
47
50
  }
48
51
 
49
52
  /** @return {import('pict/types/source/Pict-Meadow-EntityProvider.js')} */
@@ -59,11 +62,6 @@ class MeadowEndpointsRecordSetProvider extends libRecordSetProviderBase
59
62
  return this._EntityProvider;
60
63
  }
61
64
 
62
- /**
63
- * @typedef {(error?: Error, result?: T) => void} RecordSetCallback
64
- * @template T = Record<string, any>
65
- */
66
-
67
65
  /**
68
66
  * Get a record by its ID or GUID.
69
67
  *
@@ -129,6 +127,25 @@ class MeadowEndpointsRecordSetProvider extends libRecordSetProviderBase
129
127
  });
130
128
  }
131
129
 
130
+ _prepareFilterState(pEntity, pOptions, pFilterExperienceResultAddress = 'Records')
131
+ {
132
+ const tmpClauses = [].concat(this.pict.Bundle._ActiveFilterState?.[pOptions.Entity || this.options.Entity]?.FilterClauses || []);
133
+ const tmpExperience = Object.assign({}, this.pict.Bundle._ActiveFilterState?.[pOptions.Entity || this.options.Entity]?.Experience || {});
134
+ if (!tmpExperience.ResultDestinationAddress)
135
+ {
136
+ tmpExperience.ResultDestinationAddress = `Bundle._ActiveFilterState[\`${this.options.RecordSet}\`].${pFilterExperienceResultAddress}`;
137
+ }
138
+ if (!tmpExperience.Entity)
139
+ {
140
+ tmpExperience.Entity = pEntity;
141
+ }
142
+ if (pOptions.FilterString && typeof pOptions.FilterString === 'string' && pOptions.FilterString.trim().length > 0)
143
+ {
144
+ tmpClauses.push({ Type: 'RawFilter', Value: pOptions.FilterString });
145
+ }
146
+ return [ tmpClauses, tmpExperience ];
147
+ }
148
+
132
149
  /**
133
150
  * Read records from the provider.
134
151
  *
@@ -148,15 +165,16 @@ class MeadowEndpointsRecordSetProvider extends libRecordSetProviderBase
148
165
  }
149
166
  return new Promise((resolve, reject) =>
150
167
  {
151
- // using a space here, otherwise you get a `//` in the URL which breaks some stuff
152
- this.entityProvider.getEntitySetPage(tmpEntity, pOptions.FilterString ? pOptions.FilterString : ' ', pOptions.Offset || 0, pOptions.PageSize || 250, (pError, pResult) =>
168
+ const [ tmpClauses, tmpExperience ] = this._prepareFilterState(tmpEntity, pOptions);
169
+ this.pict.providers.FilterManager.loadRecordPageByFilter(tmpClauses, tmpExperience, pOptions.Offset || 0, pOptions.PageSize || 250, (pError) =>
153
170
  {
154
171
  if (pError)
155
172
  {
156
173
  return reject(pError);
157
174
  }
158
- resolve({ Records: pResult, Facets: { } });
175
+ resolve({ Records: this.pict.resolveStateFromAddress(tmpExperience.ResultDestinationAddress), Facets: { } });
159
176
  });
177
+ // using a space here, otherwise you get a `//` in the URL which breaks some stuff
160
178
  });
161
179
  }
162
180
 
@@ -192,13 +210,14 @@ class MeadowEndpointsRecordSetProvider extends libRecordSetProviderBase
192
210
  //TODO: lite support / other variants?
193
211
  return new Promise((resolve, reject) =>
194
212
  {
195
- this.entityProvider.getEntitySetRecordCount(tmpEntity, pOptions.FilterString, (pError, pCount) =>
213
+ const [ tmpClauses, tmpExperience ] = this._prepareFilterState(tmpEntity, pOptions, 'Count');
214
+ this.pict.providers.FilterManager.countRecordsByFilter(tmpClauses, tmpExperience, (pError) =>
196
215
  {
197
216
  if (pError)
198
217
  {
199
218
  return reject(pError);
200
219
  }
201
- resolve({ Count: pCount });
220
+ resolve({ Count: this.pict.resolveStateFromAddress(tmpExperience.ResultDestinationAddress) });
202
221
  });
203
222
  });
204
223
  }
@@ -331,6 +350,89 @@ class MeadowEndpointsRecordSetProvider extends libRecordSetProviderBase
331
350
  * @param {(error?: Error) => void} fCallback - The callback function.
332
351
  */
333
352
  onInitializeAsync(fCallback)
353
+ {
354
+ super.onInitializeAsync((pError) =>
355
+ {
356
+ if (this.options.FilterExperiences && typeof this.options.FilterExperiences === 'object' && !Array.isArray(this.options.FilterExperiences))
357
+ {
358
+ this.pict.Bundle._ActiveFilterState = this.pict.Bundle._ActiveFilterState || {};
359
+ this.pict.Bundle._ActiveFilterState[this.options.RecordSet] = this.pict.Bundle._ActiveFilterState[this.options.RecordSet] || {};
360
+ const tmpEntityFilterState = this.pict.Bundle._ActiveFilterState[this.options.RecordSet];
361
+ tmpEntityFilterState.Experience = tmpEntityFilterState.Experience || {};
362
+ for (const tmpKey of Object.keys(this.options.FilterExperiences))
363
+ {
364
+ const tmpExperience = this.options.FilterExperiences[tmpKey];
365
+ if (!tmpExperience.FilterCriteriaHash && !Array.isArray(tmpExperience.FilterClauses))
366
+ {
367
+ this.log.warn(`Filter experience ${tmpKey} has invalid Criteria`, { Experience: tmpExperience });
368
+ continue;
369
+ }
370
+ if (tmpExperience.FilterCriteriaHash)
371
+ {
372
+ // load from hash
373
+ const tmpClauses = this.pict.providers.FilterManager.getFilterCriteria(tmpExperience.FilterCriteriaHash);
374
+ if (!tmpClauses)
375
+ {
376
+ this.pict.log.warn(`Filter experience ${tmpKey} filter criteria hash ${tmpExperience.FilterCriteriaHash} not found`, { Experience: tmpExperience });
377
+ continue;
378
+ }
379
+ //TODO: handle Ordinal / generate if missing
380
+ this._Experiences[tmpKey] = JSON.parse(JSON.stringify(tmpExperience));
381
+ this._Experiences[tmpKey].FilterClauses = JSON.parse(JSON.stringify(tmpClauses));
382
+ for (const tmpClause of this._Experiences[tmpKey].FilterClauses)
383
+ {
384
+ tmpClause.FilterCriteriaHash = tmpExperience.FilterCriteriaHash;
385
+ if (!tmpClause.FilterByColumn && !tmpClause.CoreConnectionColumn && !tmpClause.JoinInternalConnectionColumn)
386
+ {
387
+ this.log.warn(`Filter experience ${tmpKey} clause does not have filter by column configured`, { Clause: tmpClause });
388
+ continue;
389
+ }
390
+ if (tmpClause.FilterDefinitionHash)
391
+ {
392
+ const tmpFilter = this.pict.providers.FilterManager.getFilter(tmpClause.FilterDefinitionHash);
393
+ if (!tmpFilter)
394
+ {
395
+ this.pict.log.warn(`Filter experience ${tmpKey} filter criteria hash ${tmpClause.FilterDefinitionHash} not found`, { Experience: tmpExperience });
396
+ continue;
397
+ }
398
+ Object.assign(tmpClause, tmpFilter); //TODO: is there a risk of leakage here?
399
+ if (tmpClause.FilterByColumn && typeof tmpClause.Type === 'string')
400
+ {
401
+ if (tmpClause.Type.startsWith('InternalJoin'))
402
+ {
403
+ tmpClause.JoinInternalConnectionColumn = tmpClause.FilterByColumn;
404
+ }
405
+ else if (tmpClause.Type.startsWith('ExternalJoin'))
406
+ {
407
+ tmpClause.CoreConnectionColumn = tmpClause.FilterByColumn;
408
+ }
409
+ }
410
+ }
411
+ }
412
+ if (tmpExperience.Default && !tmpEntityFilterState.FilterClauses)
413
+ {
414
+ tmpEntityFilterState.FilterClauses = JSON.parse(JSON.stringify(this._Experiences[tmpKey].FilterClauses));
415
+ }
416
+ continue;
417
+ }
418
+ this._Experiences[tmpKey] = JSON.parse(JSON.stringify(tmpExperience));
419
+ if (tmpExperience.Default && !tmpEntityFilterState.FilterClauses)
420
+ {
421
+ tmpEntityFilterState.FilterClauses = JSON.parse(JSON.stringify(tmpExperience.FilterClauses));
422
+ }
423
+ }
424
+ }
425
+ this.initializeEntitySchema(() =>
426
+ {
427
+ return fCallback(pError);
428
+ });
429
+ });
430
+ }
431
+
432
+ /**
433
+ * @param {(error?: Error) => void} fCallback - The callback function.
434
+ */
435
+ initializeEntitySchema(fCallback)
334
436
  {
335
437
  this.fable.log.info('Initializing RecordSetProvider-MeadowEndpoints');
336
438
  const checkSession = this.pict.services.PictSectionRecordSet ? this.pict.services.PictSectionRecordSet.checkSession.bind(this.pict.services.PictSectionRecordSet) : async () => true;
@@ -361,7 +463,7 @@ class MeadowEndpointsRecordSetProvider extends libRecordSetProviderBase
361
463
  {
362
464
  if (!this._Schema)
363
465
  {
364
- await new Promise((resolve, reject) => this.onInitializeAsync((pError) =>
466
+ await new Promise((resolve, reject) => this.initializeEntitySchema((pError) =>
365
467
  {
366
468
  if (pError)
367
469
  {