pict-section-recordset 1.0.15 → 1.0.18

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 (53) hide show
  1. package/example_applications/simple_entity/Simple-RecordSet-Application.js +246 -0
  2. package/package.json +4 -4
  3. package/source/application/Pict-Application-RecordSet.js +2 -0
  4. package/source/providers/RecordSet-DynamicSolver.js +305 -0
  5. package/source/providers/RecordSet-RecordProvider-Base.js +28 -0
  6. package/source/providers/RecordSet-RecordProvider-MeadowEndpoints.js +53 -3
  7. package/source/providers/RecordSet-Router.js +2 -0
  8. package/source/services/RecordsSet-MetaController.js +84 -2
  9. package/source/templates/Pict-Template-FilterView.js +172 -0
  10. package/source/views/RecordSet-Filter.js +47 -9
  11. package/source/views/dashboard/RecordSet-Dashboard-HeaderDashboard.js +17 -17
  12. package/source/views/dashboard/RecordSet-Dashboard-PaginationBottom.js +68 -0
  13. package/source/views/dashboard/RecordSet-Dashboard-PaginationTop.js +128 -0
  14. package/source/views/dashboard/RecordSet-Dashboard-RecordList.js +80 -0
  15. package/source/views/dashboard/RecordSet-Dashboard-RecordListEntry.js +121 -0
  16. package/source/views/dashboard/RecordSet-Dashboard-RecordListHeader.js +111 -0
  17. package/source/views/dashboard/RecordSet-Dashboard-Title.js +67 -0
  18. package/source/views/dashboard/RecordSet-Dashboard.js +627 -37
  19. package/source/views/error/RecordSet-Error-NotFound.json +22 -0
  20. package/source/views/list/RecordSet-List.js +20 -39
  21. package/types/application/Pict-Application-RecordSet.d.ts.map +1 -1
  22. package/types/providers/RecordSet-DynamicSolver.d.ts +158 -0
  23. package/types/providers/RecordSet-DynamicSolver.d.ts.map +1 -0
  24. package/types/providers/RecordSet-RecordProvider-Base.d.ts +19 -0
  25. package/types/providers/RecordSet-RecordProvider-Base.d.ts.map +1 -1
  26. package/types/providers/RecordSet-RecordProvider-MeadowEndpoints.d.ts +38 -5
  27. package/types/providers/RecordSet-RecordProvider-MeadowEndpoints.d.ts.map +1 -1
  28. package/types/providers/RecordSet-Router.d.ts.map +1 -1
  29. package/types/services/RecordsSet-MetaController.d.ts +20 -2
  30. package/types/services/RecordsSet-MetaController.d.ts.map +1 -1
  31. package/types/templates/Pict-Template-FilterView.d.ts +18 -0
  32. package/types/templates/Pict-Template-FilterView.d.ts.map +1 -0
  33. package/types/views/RecordSet-Filter.d.ts +28 -2
  34. package/types/views/RecordSet-Filter.d.ts.map +1 -1
  35. package/types/views/dashboard/RecordSet-Dashboard-HeaderDashboard.d.ts +5 -5
  36. package/types/views/dashboard/RecordSet-Dashboard-HeaderDashboard.d.ts.map +1 -1
  37. package/types/views/dashboard/RecordSet-Dashboard-PaginationBottom.d.ts +11 -0
  38. package/types/views/dashboard/RecordSet-Dashboard-PaginationBottom.d.ts.map +1 -0
  39. package/types/views/dashboard/RecordSet-Dashboard-PaginationTop.d.ts +11 -0
  40. package/types/views/dashboard/RecordSet-Dashboard-PaginationTop.d.ts.map +1 -0
  41. package/types/views/dashboard/RecordSet-Dashboard-RecordList.d.ts +11 -0
  42. package/types/views/dashboard/RecordSet-Dashboard-RecordList.d.ts.map +1 -0
  43. package/types/views/dashboard/RecordSet-Dashboard-RecordListEntry.d.ts +11 -0
  44. package/types/views/dashboard/RecordSet-Dashboard-RecordListEntry.d.ts.map +1 -0
  45. package/types/views/dashboard/RecordSet-Dashboard-RecordListHeader.d.ts +11 -0
  46. package/types/views/dashboard/RecordSet-Dashboard-RecordListHeader.d.ts.map +1 -0
  47. package/types/views/dashboard/RecordSet-Dashboard-Title.d.ts +11 -0
  48. package/types/views/dashboard/RecordSet-Dashboard-Title.d.ts.map +1 -0
  49. package/types/views/dashboard/RecordSet-Dashboard.d.ts +38 -0
  50. package/types/views/dashboard/RecordSet-Dashboard.d.ts.map +1 -1
  51. package/types/views/list/RecordSet-List.d.ts +0 -1
  52. package/types/views/list/RecordSet-List.d.ts.map +1 -1
  53. package/source/views/dashboard/RecordSet-Dashboard-RecordSetDashboard.js +0 -64
@@ -1,53 +1,76 @@
1
1
  const libPictRecordSetRecordView = require('../RecordSet-RecordBaseView.js');
2
2
 
3
+ const viewHeaderDashboard = require('./RecordSet-Dashboard-HeaderDashboard.js');
4
+ const viewTitle = require('./RecordSet-Dashboard-Title.js');
5
+ const viewFilters = require('../RecordSet-Filter.js');
6
+ const viewPaginationTop = require('./RecordSet-Dashboard-PaginationTop.js');
7
+ const viewRecordList = require('./RecordSet-Dashboard-RecordList.js');
8
+ const viewRecordListHeader = require('./RecordSet-Dashboard-RecordListHeader.js');
9
+ const viewRecordListEntry = require('./RecordSet-Dashboard-RecordListEntry.js');
10
+ const viewPaginationBottom = require('./RecordSet-Dashboard-PaginationBottom.js');
11
+
3
12
  /** @type {Record<string, any>} */
4
- const _DEFAULT_CONFIGURATION__Dashboard =
5
- {
6
- ViewIdentifier: 'PRSP-Dashboard',
13
+ const _DEFAULT_CONFIGURATION__Dashboard = (
14
+ {
15
+ ViewIdentifier: 'PRSP-List',
7
16
 
8
- DefaultRenderable: 'PRSP_Renderable_Dashboard',
9
- DefaultDestinationAddress: '#PRSP_Dashboard_Container',
10
- DefaultTemplateRecordAddress: false,
17
+ DefaultRenderable: 'PRSP_Renderable_List',
18
+ DefaultDestinationAddress: '#PRSP_Container',
19
+ DefaultTemplateRecordAddress: false,
11
20
 
12
- // If this is set to true, when the App initializes this will.
13
- // While the App initializes, initialize will be called.
14
- AutoInitialize: false,
15
- AutoInitializeOrdinal: 0,
21
+ // If this is set to true, when the App initializes this will.
22
+ // While the App initializes, initialize will be called.
23
+ AutoInitialize: false,
24
+ AutoInitializeOrdinal: 0,
16
25
 
17
- // If this is set to true, when the App autorenders (on load) this will.
18
- // After the App initializes, render will be called.
19
- AutoRender: false,
20
- AutoRenderOrdinal: 0,
26
+ // If this is set to true, when the App autorenders (on load) this will.
27
+ // After the App initializes, render will be called.
28
+ AutoRender: false,
29
+ AutoRenderOrdinal: 0,
21
30
 
22
- AutoSolveWithApp: false,
23
- AutoSolveOrdinal: 0,
31
+ AutoSolveWithApp: false,
32
+ AutoSolveOrdinal: 0,
24
33
 
25
- CSS: false,
26
- CSSPriority: 500,
34
+ CSS: false,
35
+ CSSPriority: 500,
27
36
 
28
- Templates:
29
- [
30
- {
31
- Hash: 'PRSP-Dashboard-Template',
32
- Template: /*html*/`
37
+ Templates:
38
+ [
39
+ {
40
+ Hash: 'PRSP-Dashboard-Template',
41
+ Template: /*html*/`
33
42
  <!-- DefaultPackage pict view template: [PRSP-Dashboard-Template] -->
43
+ <section id="PRSP_List_Container">
44
+ {~V:PRSP-Dashboard-Title~}
45
+ {~V:PRSP-Dashboard-HeaderDashboard~}
46
+ {~FV:PRSP-Filters:Dashboard~}
47
+ {~V:PRSP-Dashboard-PaginationTop~}
48
+ {~V:PRSP-Dashboard-RecordList~}
49
+ {~V:PRSP-Dashboard-PaginationBottom~}
50
+ </section>
34
51
  <!-- DefaultPackage end view template: [PRSP-Dashboard-Template] -->
35
- `
36
- }
37
- ],
52
+ `
53
+ },
54
+ {
55
+ Hash: 'PRSP-Dashboard-Template-Record',
56
+ Template: /*html*/`
57
+ <!-- DefaultPackage end view template: [PRSP-Dashboard-Template] -->
58
+ `
59
+ }
60
+ ],
38
61
 
39
- Renderables:
40
- [
41
- {
42
- RenderableHash: 'PRSP_Renderable_Dashboard',
43
- TemplateHash: 'PRSP-Dashboard-Template',
44
- DestinationAddress: '#PRSP_Dashboard_Container',
45
- RenderMethod: 'replace'
46
- }
47
- ],
62
+ Renderables:
63
+ [
64
+ {
65
+ RenderableHash: 'PRSP_Renderable_List',
66
+ TemplateHash: 'PRSP-Dashboard-Template',
67
+ DestinationAddress: '#PRSP_Container',
68
+ RenderMethod: 'replace'
69
+ }
70
+ ],
48
71
 
49
- Manifests: {}
50
- };
72
+ Manifests: {}
73
+ });
51
74
 
52
75
  class viewRecordSetDashboard extends libPictRecordSetRecordView
53
76
  {
@@ -55,6 +78,573 @@ class viewRecordSetDashboard extends libPictRecordSetRecordView
55
78
  {
56
79
  let tmpOptions = Object.assign({}, _DEFAULT_CONFIGURATION__Dashboard, pOptions);
57
80
  super(pFable, tmpOptions, pServiceHash);
81
+
82
+ this.childViews = {
83
+ headerList: null,
84
+ title: null,
85
+ paginationTop: null,
86
+ recordList: null,
87
+ recordListHeader: null,
88
+ recordListEntry: null,
89
+ paginationBottom: null
90
+ };
91
+ }
92
+
93
+ handleRecordSetDashboardRoute(pRoutePayload)
94
+ {
95
+ if (typeof(pRoutePayload) != 'object')
96
+ {
97
+ return;
98
+ throw new Error(`Pict RecordSet List view route handler called with invalid route payload.`);
99
+ }
100
+ if (!pRoutePayload.data || !pRoutePayload.data.RecordSet)
101
+ {
102
+ return;
103
+ }
104
+
105
+ //_Pict.PictSectionRecordSet.recordSetProviderConfigurations['Book'], 'RSP-Provider-Book'
106
+ // FIXME: Not in love with this but good enough to start.
107
+ // FIXME: Typescript mumbo jumbo
108
+ // if (!('PictSectionRecordSet' in this.pict))
109
+ // {
110
+ // return false;
111
+ // }
112
+ const tmpProviderConfiguration = this.pict.PictSectionRecordSet.recordSetProviderConfigurations[pRoutePayload.data.RecordSet];
113
+ if (!tmpProviderConfiguration)
114
+ {
115
+ this.pict.log.error(`RecordSetDashboard: No record set configuration found for ${pRoutePayload.data.RecordSet}. List Render failed.`);
116
+ this.fable.providers.RecordSetRouter.pictRouter.navigate('/PSRS/404');
117
+ return;
118
+ }
119
+ const tmpProviderHash = `RSP-Provider-${pRoutePayload.data.RecordSet}`;
120
+
121
+ const tmpFilterString = pRoutePayload.data.FilterString || '';
122
+
123
+ const tmpOffset = pRoutePayload.data.Offset ? pRoutePayload.data.Offset : 0;
124
+ const tmpPageSize = pRoutePayload.data.PageSize ? pRoutePayload.data.PageSize : 100;
125
+
126
+ if (pRoutePayload.data.DashboardHash)
127
+ {
128
+ return this.renderSpecificDashboard(pRoutePayload.data.DashboardHash, tmpProviderConfiguration, tmpProviderHash, tmpFilterString, tmpOffset, tmpPageSize);
129
+ }
130
+ return this.renderDashboard(tmpProviderConfiguration, tmpProviderHash, tmpFilterString, tmpOffset, tmpPageSize);
131
+ }
132
+
133
+ /**
134
+ * @param {import('pict-router')} pPictRouter
135
+ */
136
+ addRoutes(pPictRouter)
137
+ {
138
+ pPictRouter.router.on('/PSRS/:RecordSet/Dashboard/FilteredTo/:FilterString/:Offset/:PageSize', this.handleRecordSetDashboardRoute.bind(this));
139
+ pPictRouter.router.on('/PSRS/:RecordSet/Dashboard/FilteredTo/:FilterString', this.handleRecordSetDashboardRoute.bind(this));
140
+ pPictRouter.router.on('/PSRS/:RecordSet/Dashboard/:Offset/:PageSize', this.handleRecordSetDashboardRoute.bind(this));
141
+ pPictRouter.router.on('/PSRS/:RecordSet/Dashboard/:Offset', this.handleRecordSetDashboardRoute.bind(this));
142
+ pPictRouter.router.on('/PSRS/:RecordSet/Dashboard', this.handleRecordSetDashboardRoute.bind(this));
143
+
144
+ pPictRouter.router.on('/PSRS/:RecordSet/SpecificDashboard/:DashboardHash/FilteredTo/:FilterString/:Offset/:PageSize', this.handleRecordSetDashboardRoute.bind(this));
145
+ pPictRouter.router.on('/PSRS/:RecordSet/SpecificDashboard/:DashboardHash/FilteredTo/:FilterString', this.handleRecordSetDashboardRoute.bind(this));
146
+ pPictRouter.router.on('/PSRS/:RecordSet/SpecificDashboard/:DashboardHash/:Offset/:PageSize', this.handleRecordSetDashboardRoute.bind(this));
147
+ pPictRouter.router.on('/PSRS/:RecordSet/SpecificDashboard/:DashboardHash/:Offset', this.handleRecordSetDashboardRoute.bind(this));
148
+ pPictRouter.router.on('/PSRS/:RecordSet/SpecificDashboard/:DashboardHash', this.handleRecordSetDashboardRoute.bind(this));
149
+ pPictRouter.router.resolve();
150
+ return true;
151
+ }
152
+
153
+ onBeforeRenderList(pRecordListData)
154
+ {
155
+ return pRecordListData;
156
+ }
157
+
158
+ dynamicallyGenerateColumns(pRecordListData)
159
+ {
160
+ pRecordListData.TableCells = [];
161
+ const tmpEntity = pRecordListData.RecordSetConfiguration.Entity;
162
+ this.excludedByDefaultCells = [
163
+ 'ID' + tmpEntity,
164
+ 'GUID' + tmpEntity,
165
+ 'CreateDate',
166
+ 'CreatingIDUser',
167
+ 'DeleteDate',
168
+ 'Deleted',
169
+ 'DeletingIDUser',
170
+ 'UpdateDate',
171
+ 'UpdatingIDUser',
172
+ ];
173
+
174
+ const tmpSchema = pRecordListData.RecordSchema;
175
+ const tmpProperties = tmpSchema?.properties;
176
+ // loop throught the schema and add the columns to the tableCells
177
+ for (const tmpColumn in tmpProperties)
178
+ {
179
+ if (tmpProperties.hasOwnProperty(tmpColumn))
180
+ {
181
+ // Check if the column is excluded by the default list of columns (or is not a GUID/ID)
182
+ if (this.excludedByDefaultCells.includes(tmpColumn) === false)
183
+ {
184
+ pRecordListData.TableCells.push({
185
+ Key: tmpColumn,
186
+ DisplayName: tmpProperties?.[tmpColumn].title || tmpColumn,
187
+ ManifestHash: 'Default',
188
+ PictDashboard:
189
+ {
190
+ ValueTemplate: '{~DVBK:Record.Payload:Record.Data.Key~}',
191
+ },
192
+ });
193
+ }
194
+ }
195
+ }
196
+ return pRecordListData;
197
+ }
198
+
199
+ /**
200
+ * @param {string} pDashboardHash
201
+ * @param {Record<string, any>} pRecordSetConfiguration
202
+ * @param {string} pProviderHash
203
+ * @param {string} pFilterString
204
+ * @param {number} pOffset
205
+ * @param {number} pPageSize
206
+ *
207
+ * @return {Promise<void>}
208
+ */
209
+ async renderSpecificDashboard(pDashboardHash, pRecordSetConfiguration, pProviderHash, pFilterString, pOffset, pPageSize)
210
+ {
211
+ if (!pRecordSetConfiguration)
212
+ {
213
+ this.pict.log.error(`RecordSetDashboard: No record set configuration found for ${pDashboardHash}. List Render failed.`);
214
+ return;
215
+ }
216
+ // Get the records
217
+ if (!(pProviderHash in this.pict.providers))
218
+ {
219
+ this.pict.log.error(`RecordSetDashboard: No provider found for ${pProviderHash} in ${pRecordSetConfiguration.RecordSet}. List Render failed.`);
220
+ return;
221
+ }
222
+
223
+ let tmpManifest;
224
+ if (pDashboardHash)
225
+ {
226
+ tmpManifest = this.pict.PictSectionRecordSet.manifestDefinitions[pDashboardHash];
227
+ }
228
+ let tmpTitle = pRecordSetConfiguration.Title || pRecordSetConfiguration.RecordSet;
229
+ if (tmpManifest && tmpManifest.TitleTemplate)
230
+ {
231
+ tmpTitle = this.pict.parseTemplate(tmpManifest.TitleTemplate, pRecordSetConfiguration);
232
+ }
233
+
234
+ let tmpRecordDashboardData =
235
+ {
236
+ "Title": tmpTitle,
237
+
238
+ "RecordSet": pRecordSetConfiguration.RecordSet,
239
+ "RecordSetConfiguration": pRecordSetConfiguration,
240
+
241
+ "RenderDestination": this.options.DefaultDestinationAddress,
242
+
243
+ "FilterString": pFilterString ? encodeURIComponent(pFilterString) : undefined,
244
+
245
+ "Records": { "Records": [] },
246
+ "TotalRecordCount": { "Count": -1 },
247
+
248
+ "Offset": pOffset || 0,
249
+ "PageSize": pPageSize || 100,
250
+ "DashboardHash": pDashboardHash,
251
+ };
252
+
253
+ // TODO: There are still problems with the way these have nested data. Discuss how we might move that around
254
+ // Fetch the records
255
+ tmpRecordDashboardData.Records = await this.pict.providers[pProviderHash].getDecoratedRecords(tmpRecordDashboardData);
256
+ // Get the total record count
257
+ tmpRecordDashboardData.TotalRecordCount = await this.pict.providers[pProviderHash].getRecordSetCount(tmpRecordDashboardData);
258
+ // Get the record schema
259
+ tmpRecordDashboardData.RecordSchema = await this.pict.providers[pProviderHash].getRecordSchema();
260
+
261
+ // TODO: This should be coming from the schema but that can come after we discuss how we deal with default routing
262
+ tmpRecordDashboardData.GUIDAddress = `GUID${this.pict.providers[pProviderHash].options.Entity}`;
263
+
264
+ // Get the "page end record number" for the current page (e.g. for messaging like Record 700 to 800 of 75,000)
265
+ tmpRecordDashboardData.PageEnd = parseInt(tmpRecordDashboardData.Offset) + tmpRecordDashboardData.Records.Records.length;
266
+
267
+ // Compute the number of pages total
268
+ tmpRecordDashboardData.PageCount = Math.ceil(tmpRecordDashboardData.TotalRecordCount.Count / tmpRecordDashboardData.PageSize);
269
+
270
+ // Generate each page's links.
271
+ // TODO: This is fast and cool; any reason not to?
272
+ // Get "bookmarks" as references to the array of page links.
273
+ tmpRecordDashboardData.PageLinkBookmarks = (
274
+ {
275
+ Current: Math.floor(tmpRecordDashboardData.Offset / tmpRecordDashboardData.PageSize)
276
+ });
277
+ tmpRecordDashboardData.PageLinks = [];
278
+ for (let i = 0; i < tmpRecordDashboardData.PageCount; i++)
279
+ {
280
+ if (tmpRecordDashboardData.FilterString)
281
+ {
282
+ tmpRecordDashboardData.PageLinks.push(
283
+ {
284
+ Page: i + 1,
285
+ RelativeOffset: i - tmpRecordDashboardData.PageLinkBookmarks.Current,
286
+ URL: `#/PSRS/${tmpRecordDashboardData.RecordSet}/SpecificDashboard/${pDashboardHash}/FilteredTo/${tmpRecordDashboardData.FilterString}/${i * tmpRecordDashboardData.PageSize}/${tmpRecordDashboardData.PageSize}`
287
+ });
288
+ }
289
+ else
290
+ {
291
+ tmpRecordDashboardData.PageLinks.push(
292
+ {
293
+ Page: i + 1,
294
+ RelativeOffset: i - tmpRecordDashboardData.PageLinkBookmarks.Current,
295
+ URL: `#/PSRS/${tmpRecordDashboardData.RecordSet}/SpecificDashboard/${pDashboardHash}/${i * tmpRecordDashboardData.PageSize}/${tmpRecordDashboardData.PageSize}`
296
+ });
297
+ }
298
+ }
299
+
300
+ //FIXME: short-term workaround to not blow up the tempplate rendering with way too many links
301
+ const linkRangeStart = Math.max(0, tmpRecordDashboardData.PageLinkBookmarks.Current - 10);
302
+ const linkRangeEnd = Math.min(tmpRecordDashboardData.PageLinks.length, tmpRecordDashboardData.PageLinkBookmarks.Current + 10);
303
+ tmpRecordDashboardData.PageLinksLimited = tmpRecordDashboardData.PageLinks.slice(linkRangeStart, linkRangeEnd);
304
+ if (linkRangeStart > 0)
305
+ {
306
+ if (tmpRecordDashboardData.FilterString)
307
+ {
308
+ tmpRecordDashboardData.PageLinksLimited.unshift(
309
+ {
310
+ Page: 1,
311
+ RelativeOffset: -tmpRecordDashboardData.PageLinkBookmarks.Current,
312
+ URL: `#/PSRS/${tmpRecordDashboardData.RecordSet}/SpecificDashboard/${pDashboardHash}/FilteredTo/${tmpRecordDashboardData.FilterString}/${tmpRecordDashboardData.PageSize}/${tmpRecordDashboardData.PageSize}`
313
+ });
314
+ }
315
+ else
316
+ {
317
+ tmpRecordDashboardData.PageLinksLimited.unshift(
318
+ {
319
+ Page: 1,
320
+ RelativeOffset: -tmpRecordDashboardData.PageLinkBookmarks.Current,
321
+ URL: `#/PSRS/${tmpRecordDashboardData.RecordSet}/SpecificDashboard/${pDashboardHash}/0/${tmpRecordDashboardData.PageSize}`
322
+ });
323
+ }
324
+ }
325
+ if (linkRangeEnd < tmpRecordDashboardData.PageLinks.length)
326
+ {
327
+ if (tmpRecordDashboardData.FilterString)
328
+ {
329
+ tmpRecordDashboardData.PageLinksLimited.push(
330
+ {
331
+ Page: tmpRecordDashboardData.PageCount,
332
+ RelativeOffset: (tmpRecordDashboardData.PageCount - 1) - tmpRecordDashboardData.PageLinkBookmarks.Current,
333
+ URL: `#/PSRS/${tmpRecordDashboardData.RecordSet}/SpecificDashboard/${pDashboardHash}/FilteredTo/${tmpRecordDashboardData.FilterString}/${(tmpRecordDashboardData.PageCount - 1) * tmpRecordDashboardData.PageSize}/${tmpRecordDashboardData.PageSize}`
334
+ });
335
+ }
336
+ else
337
+ {
338
+ tmpRecordDashboardData.PageLinksLimited.push(
339
+ {
340
+ Page: tmpRecordDashboardData.PageCount,
341
+ RelativeOffset: (tmpRecordDashboardData.PageCount - 1) - tmpRecordDashboardData.PageLinkBookmarks.Current,
342
+ URL: `#/PSRS/${tmpRecordDashboardData.RecordSet}/SpecificDashboard/${pDashboardHash}/${(tmpRecordDashboardData.PageCount - 1) * tmpRecordDashboardData.PageSize}/${tmpRecordDashboardData.PageSize}`
343
+ });
344
+ }
345
+ }
346
+
347
+ tmpRecordDashboardData.PageLinkBookmarks.Previous = tmpRecordDashboardData.PageLinkBookmarks.Current - 1;
348
+ tmpRecordDashboardData.PageLinkBookmarks.Next = tmpRecordDashboardData.PageLinkBookmarks.Current + 1;
349
+ tmpRecordDashboardData.PageLinkBookmarks.ShowPreviousLink = true;
350
+ tmpRecordDashboardData.PageLinkBookmarks.ShowNextLink = true;
351
+ if (tmpRecordDashboardData.PageLinkBookmarks.Previous < 0)
352
+ {
353
+ tmpRecordDashboardData.PageLinkBookmarks.PreviousLink = false;
354
+ tmpRecordDashboardData.PageLinkBookmarks.ShowPreviousLink = false;
355
+ }
356
+ else
357
+ {
358
+ tmpRecordDashboardData.PageLinkBookmarks.PreviousLink = tmpRecordDashboardData.PageLinks[tmpRecordDashboardData.PageLinkBookmarks.Previous];
359
+ }
360
+ if (tmpRecordDashboardData.PageLinkBookmarks.Next >= tmpRecordDashboardData.PageLinks.length)
361
+ {
362
+ tmpRecordDashboardData.PageLinkBookmarks.NextLink = false;
363
+ tmpRecordDashboardData.PageLinkBookmarks.ShowNextLink = false;
364
+ }
365
+ else
366
+ {
367
+ tmpRecordDashboardData.PageLinkBookmarks.NextLink = tmpRecordDashboardData.PageLinks[tmpRecordDashboardData.PageLinkBookmarks.Next];
368
+ }
369
+
370
+ if (pDashboardHash)
371
+ {
372
+ tmpRecordDashboardData.TableCells = tmpManifest?.TableCells;
373
+ }
374
+ if (!tmpRecordDashboardData.TableCells)
375
+ {
376
+ tmpRecordDashboardData.TableCells = [];
377
+ // Put code here to preprocess columns into other data parts.
378
+ /*
379
+ "RecordSetListManifestOnly": false,
380
+
381
+ "RecordSetListManifests": [ "Bestsellers", "Underdogs", "NewReleases" ],
382
+ "RecordSetDashboardManifests": [ "Bestsellers" ],
383
+ */
384
+ if (tmpRecordDashboardData.RecordSetConfiguration.hasOwnProperty('RecordSetListColumns'))
385
+ {
386
+ tmpRecordDashboardData.TableCells = tmpRecordDashboardData.RecordSetConfiguration.RecordSetListColumns;
387
+ }
388
+ else
389
+ {
390
+ this.dynamicallyGenerateColumns(tmpRecordDashboardData);
391
+ }
392
+ }
393
+
394
+ tmpRecordDashboardData = this.onBeforeRenderList(tmpRecordDashboardData);
395
+
396
+ this.pict.providers.DynamicSolver.solveDashboard(tmpManifest || { }, tmpRecordDashboardData.Records.Records);
397
+
398
+ this.renderAsync('PRSP_Renderable_List', tmpRecordDashboardData.RenderDestination, tmpRecordDashboardData,
399
+ function (pError)
400
+ {
401
+ if (pError)
402
+ {
403
+ this.pict.log.error(`RecordSetDashboard: Error rendering list ${pError}`, tmpRecordDashboardData);
404
+ return;
405
+ }
406
+
407
+ if (this.pict.LogNoisiness > 0)
408
+ {
409
+ this.pict.log.info(`RecordSetDashboard: Rendered list ${tmpRecordDashboardData.RecordSet} with ${tmpRecordDashboardData.Records.Records.length} records.`, tmpRecordDashboardData);
410
+ }
411
+ else
412
+ {
413
+ this.pict.log.info(`RecordSetDashboard: Rendered list ${tmpRecordDashboardData.RecordSet} with ${tmpRecordDashboardData.Records.Records.length} records.`);
414
+ }
415
+ }.bind(this));
416
+ }
417
+
418
+ /**
419
+ * @param {Record<string, any>} pRecordSetConfiguration
420
+ * @param {string} pProviderHash
421
+ * @param {string} pFilterString
422
+ * @param {number} pOffset
423
+ * @param {number} pPageSize
424
+ *
425
+ * @return {Promise<void>}
426
+ */
427
+ async renderDashboard(pRecordSetConfiguration, pProviderHash, pFilterString, pOffset, pPageSize)
428
+ {
429
+ if (!pRecordSetConfiguration)
430
+ {
431
+ this.pict.log.error(`RecordSetDashboard: No record set configuration found. List Render failed.`);
432
+ return;
433
+ }
434
+ // Get the records
435
+ if (!(pProviderHash in this.pict.providers))
436
+ {
437
+ this.pict.log.error(`RecordSetDashboard: No provider found for ${pProviderHash} in ${pRecordSetConfiguration.RecordSet}. List Render failed.`);
438
+ return;
439
+ }
440
+
441
+ let tmpRecordDashboardData =
442
+ {
443
+ "Title": pRecordSetConfiguration.Title || pRecordSetConfiguration.RecordSet,
444
+
445
+ "RecordSet": pRecordSetConfiguration.RecordSet,
446
+ "RecordSetConfiguration": pRecordSetConfiguration,
447
+
448
+ "RenderDestination": this.options.DefaultDestinationAddress,
449
+
450
+ "FilterString": pFilterString ? encodeURIComponent(pFilterString) : undefined,
451
+
452
+ "Records": { "Records": [] },
453
+ "TotalRecordCount": { "Count": -1 },
454
+
455
+ "Offset": pOffset || 0,
456
+ "PageSize": pPageSize || 100,
457
+ };
458
+
459
+ // TODO: There are still problems with the way these have nested data. Discuss how we might move that around
460
+ // Fetch the records
461
+ const [ tmpRecords, tmpTotalRecordCount, tmpRecordSchema ] = await Promise.all([
462
+ this.pict.providers[pProviderHash].getRecords(tmpRecordDashboardData),
463
+ this.pict.providers[pProviderHash].getRecordSetCount(tmpRecordDashboardData),
464
+ this.pict.providers[pProviderHash].getRecordSchema(),
465
+ ]);
466
+ tmpRecordDashboardData.Records = tmpRecords;
467
+ // Get the total record count
468
+ tmpRecordDashboardData.TotalRecordCount = tmpTotalRecordCount;
469
+ // Get the record schema
470
+ tmpRecordDashboardData.RecordSchema = tmpRecordSchema;
471
+
472
+ // TODO: This should be coming from the schema but that can come after we discuss how we deal with default routing
473
+ tmpRecordDashboardData.GUIDAddress = `GUID${this.pict.providers[pProviderHash].options.Entity}`;
474
+
475
+ // Get the "page end record number" for the current page (e.g. for messaging like Record 700 to 800 of 75,000)
476
+ tmpRecordDashboardData.PageEnd = parseInt(tmpRecordDashboardData.Offset) + tmpRecordDashboardData.Records.Records.length;
477
+
478
+ // Compute the number of pages total
479
+ tmpRecordDashboardData.PageCount = Math.ceil(tmpRecordDashboardData.TotalRecordCount.Count / tmpRecordDashboardData.PageSize);
480
+
481
+ // Generate each page's links.
482
+ // TODO: This is fast and cool; any reason not to?
483
+ // Get "bookmarks" as references to the array of page links.
484
+ tmpRecordDashboardData.PageLinkBookmarks = (
485
+ {
486
+ Current: Math.floor(tmpRecordDashboardData.Offset / tmpRecordDashboardData.PageSize)
487
+ });
488
+ tmpRecordDashboardData.PageLinks = [];
489
+ for (let i = 0; i < tmpRecordDashboardData.PageCount; i++)
490
+ {
491
+ if (tmpRecordDashboardData.FilterString)
492
+ {
493
+ tmpRecordDashboardData.PageLinks.push(
494
+ {
495
+ Page: i + 1,
496
+ RelativeOffset: i - tmpRecordDashboardData.PageLinkBookmarks.Current,
497
+ URL: `#/PSRS/${tmpRecordDashboardData.RecordSet}/Dashboard/FilteredTo/${tmpRecordDashboardData.FilterString}/${i * tmpRecordDashboardData.PageSize}/${tmpRecordDashboardData.PageSize}`
498
+ });
499
+ }
500
+ else
501
+ {
502
+ tmpRecordDashboardData.PageLinks.push(
503
+ {
504
+ Page: i + 1,
505
+ RelativeOffset: i - tmpRecordDashboardData.PageLinkBookmarks.Current,
506
+ URL: `#/PSRS/${tmpRecordDashboardData.RecordSet}/Dashboard/${i * tmpRecordDashboardData.PageSize}/${tmpRecordDashboardData.PageSize}`
507
+ });
508
+ }
509
+ }
510
+
511
+ //FIXME: short-term workaround to not blow up the tempplate rendering with way too many links
512
+ const linkRangeStart = Math.max(0, tmpRecordDashboardData.PageLinkBookmarks.Current - 10);
513
+ const linkRangeEnd = Math.min(tmpRecordDashboardData.PageLinks.length, tmpRecordDashboardData.PageLinkBookmarks.Current + 10);
514
+ tmpRecordDashboardData.PageLinksLimited = tmpRecordDashboardData.PageLinks.slice(linkRangeStart, linkRangeEnd);
515
+ if (linkRangeStart > 0)
516
+ {
517
+ if (tmpRecordDashboardData.FilterString)
518
+ {
519
+ tmpRecordDashboardData.PageLinksLimited.unshift(
520
+ {
521
+ Page: 1,
522
+ RelativeOffset: -tmpRecordDashboardData.PageLinkBookmarks.Current,
523
+ URL: `#/PSRS/${tmpRecordDashboardData.RecordSet}/Dashboard/FilteredTo/${tmpRecordDashboardData.FilterString}/${tmpRecordDashboardData.PageSize}/${tmpRecordDashboardData.PageSize}`
524
+ });
525
+ }
526
+ else
527
+ {
528
+ tmpRecordDashboardData.PageLinksLimited.unshift(
529
+ {
530
+ Page: 1,
531
+ RelativeOffset: -tmpRecordDashboardData.PageLinkBookmarks.Current,
532
+ URL: `#/PSRS/${tmpRecordDashboardData.RecordSet}/Dashboard/${0}/${tmpRecordDashboardData.PageSize}`
533
+ });
534
+ }
535
+ }
536
+ if (linkRangeEnd < tmpRecordDashboardData.PageLinks.length)
537
+ {
538
+ if (tmpRecordDashboardData.FilterString)
539
+ {
540
+ tmpRecordDashboardData.PageLinksLimited.push(
541
+ {
542
+ Page: tmpRecordDashboardData.PageCount,
543
+ RelativeOffset: (tmpRecordDashboardData.PageCount - 1) - tmpRecordDashboardData.PageLinkBookmarks.Current,
544
+ URL: `#/PSRS/${tmpRecordDashboardData.RecordSet}/Dashboard/FilteredTo/${tmpRecordDashboardData.FilterString}/${(tmpRecordDashboardData.PageCount - 1) * tmpRecordDashboardData.PageSize}/${tmpRecordDashboardData.PageSize}`
545
+ });
546
+ }
547
+ else
548
+ {
549
+ tmpRecordDashboardData.PageLinksLimited.push(
550
+ {
551
+ Page: tmpRecordDashboardData.PageCount,
552
+ RelativeOffset: (tmpRecordDashboardData.PageCount - 1) - tmpRecordDashboardData.PageLinkBookmarks.Current,
553
+ URL: `#/PSRS/${tmpRecordDashboardData.RecordSet}/Dashboard/${(tmpRecordDashboardData.PageCount - 1) * tmpRecordDashboardData.PageSize}/${tmpRecordDashboardData.PageSize}`
554
+ });
555
+ }
556
+ }
557
+
558
+ tmpRecordDashboardData.PageLinkBookmarks.Previous = tmpRecordDashboardData.PageLinkBookmarks.Current - 1;
559
+ tmpRecordDashboardData.PageLinkBookmarks.Next = tmpRecordDashboardData.PageLinkBookmarks.Current + 1;
560
+ tmpRecordDashboardData.PageLinkBookmarks.ShowPreviousLink = true;
561
+ tmpRecordDashboardData.PageLinkBookmarks.ShowNextLink = true;
562
+ if (tmpRecordDashboardData.PageLinkBookmarks.Previous < 0)
563
+ {
564
+ tmpRecordDashboardData.PageLinkBookmarks.PreviousLink = false;
565
+ tmpRecordDashboardData.PageLinkBookmarks.ShowPreviousLink = false;
566
+ }
567
+ else
568
+ {
569
+ tmpRecordDashboardData.PageLinkBookmarks.PreviousLink = tmpRecordDashboardData.PageLinks[tmpRecordDashboardData.PageLinkBookmarks.Previous];
570
+ }
571
+ if (tmpRecordDashboardData.PageLinkBookmarks.Next >= tmpRecordDashboardData.PageLinks.length)
572
+ {
573
+ tmpRecordDashboardData.PageLinkBookmarks.NextLink = false;
574
+ tmpRecordDashboardData.PageLinkBookmarks.ShowNextLink = false;
575
+ }
576
+ else
577
+ {
578
+ tmpRecordDashboardData.PageLinkBookmarks.NextLink = tmpRecordDashboardData.PageLinks[tmpRecordDashboardData.PageLinkBookmarks.Next];
579
+ }
580
+
581
+ tmpRecordDashboardData.TableCells = [];
582
+ // Put code here to preprocess columns into other data parts.
583
+ /*
584
+ "RecordSetListManifestOnly": false,
585
+
586
+ "RecordSetListManifests": [ "Bestsellers", "Underdogs", "NewReleases" ],
587
+ "RecordSetDashboardManifests": [ "Bestsellers" ],
588
+ */
589
+ if (tmpRecordDashboardData.RecordSetConfiguration.hasOwnProperty('RecordSetListColumns'))
590
+ {
591
+ tmpRecordDashboardData.TableCells = tmpRecordDashboardData.RecordSetConfiguration.RecordSetListColumns;
592
+ }
593
+ else
594
+ {
595
+ this.dynamicallyGenerateColumns(tmpRecordDashboardData);
596
+ }
597
+
598
+ tmpRecordDashboardData = this.onBeforeRenderList(tmpRecordDashboardData);
599
+
600
+ const tmpManifest = { Scope: 'Default', Descriptors: { }, TableCells: tmpRecordDashboardData.TableCells };
601
+ for (const tmpCell of tmpRecordDashboardData.TableCells)
602
+ {
603
+ tmpManifest.Descriptors[tmpCell.Key] = { Hash: tmpCell.Key, PictDashboard: tmpCell.PictDashboard };
604
+ }
605
+ this.pict.providers.DynamicSolver.solveDashboard(tmpManifest, tmpRecordDashboardData.Records.Records);
606
+
607
+ this.renderAsync('PRSP_Renderable_List', tmpRecordDashboardData.RenderDestination, tmpRecordDashboardData,
608
+ function (pError)
609
+ {
610
+ if (pError)
611
+ {
612
+ this.pict.log.error(`RecordSetDashboard: Error rendering list ${pError}`, tmpRecordDashboardData);
613
+ return;
614
+ }
615
+
616
+ if (this.pict.LogNoisiness > 0)
617
+ {
618
+ this.pict.log.info(`RecordSetDashboard: Rendered list ${tmpRecordDashboardData.RecordSet} with ${tmpRecordDashboardData.Records.Records.length} records.`, tmpRecordDashboardData);
619
+ }
620
+ else
621
+ {
622
+ this.pict.log.info(`RecordSetDashboard: Rendered list ${tmpRecordDashboardData.RecordSet} with ${tmpRecordDashboardData.Records.Records.length} records.`);
623
+ }
624
+ }.bind(this));
625
+ }
626
+
627
+ onInitialize()
628
+ {
629
+ this.childViews.headerList = this.pict.addView('PRSP-Dashboard-HeaderDashboard', viewHeaderDashboard.default_configuration, viewHeaderDashboard);
630
+ this.childViews.title = this.pict.addView('PRSP-Dashboard-Title', viewTitle.default_configuration, viewTitle);
631
+ this.childViews.filters = this.pict.views['PRSP-Filters'] || this.pict.addView('PRSP-Filters', { }, viewFilters);
632
+ this.childViews.paginationTop = this.pict.addView('PRSP-Dashboard-PaginationTop', viewPaginationTop.default_configuration, viewPaginationTop);
633
+ this.childViews.recordList = this.pict.addView('PRSP-Dashboard-RecordList', viewRecordList.default_configuration, viewRecordList);
634
+ this.childViews.recordListHeader = this.pict.addView('PRSP-Dashboard-RecordListHeader', viewRecordListHeader.default_configuration, viewRecordListHeader);
635
+ this.childViews.recordListEntry = this.pict.addView('PRSP-Dashboard-RecordListEntry', viewRecordListEntry.default_configuration, viewRecordListEntry);
636
+ this.childViews.paginationBottom = this.pict.addView('PRSP-Dashboard-PaginationBottom', viewPaginationBottom.default_configuration, viewPaginationBottom);
637
+
638
+ // Initialize the subviews
639
+ this.childViews.headerList.initialize();
640
+ this.childViews.title.initialize();
641
+ this.childViews.paginationTop.initialize();
642
+ this.childViews.recordList.initialize();
643
+ this.childViews.recordListHeader.initialize();
644
+ this.childViews.recordListEntry.initialize();
645
+ this.childViews.paginationBottom.initialize();
646
+
647
+ return super.onInitialize();
58
648
  }
59
649
  }
60
650