pict-section-recordset 1.0.14 → 1.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/example_applications/simple_entity/Simple-RecordSet-Application.js +113 -0
- package/package.json +3 -3
- package/source/application/Pict-Application-RecordSet.js +1 -0
- package/source/providers/RecordSet-Link-Manager.js +2 -1
- package/source/providers/RecordSet-RecordProvider-Base.js +28 -0
- package/source/providers/RecordSet-RecordProvider-MeadowEndpoints.js +53 -3
- package/source/providers/RecordSet-Router.js +1 -0
- package/source/services/RecordsSet-MetaController.js +85 -1
- package/source/templates/Pict-Template-FilterView.js +172 -0
- package/source/views/RecordSet-Filter.js +47 -9
- package/source/views/RecordSet-RecordBaseView.js +1 -0
- package/source/views/RecordsSet-MacroView.js +1 -0
- package/source/views/dashboard/RecordSet-Dashboard-HeaderDashboard.js +18 -17
- package/source/views/dashboard/RecordSet-Dashboard-PaginationBottom.js +68 -0
- package/source/views/dashboard/RecordSet-Dashboard-PaginationTop.js +128 -0
- package/source/views/dashboard/RecordSet-Dashboard-RecordList.js +80 -0
- package/source/views/dashboard/RecordSet-Dashboard-RecordListEntry.js +121 -0
- package/source/views/dashboard/RecordSet-Dashboard-RecordListHeader.js +99 -0
- package/source/views/dashboard/RecordSet-Dashboard-TabBarDashboard.js +1 -0
- package/source/views/dashboard/RecordSet-Dashboard-Title.js +67 -0
- package/source/views/dashboard/RecordSet-Dashboard.js +355 -37
- package/source/views/edit/RecordSet-Edit-HeaderEdit.js +1 -0
- package/source/views/edit/RecordSet-Edit-RecordEdit.js +1 -0
- package/source/views/edit/RecordSet-Edit-RecordEditControls.js +1 -0
- package/source/views/edit/RecordSet-Edit-RecordEditExtra.js +1 -0
- package/source/views/edit/RecordSet-Edit-TabBarEdit.js +1 -0
- package/source/views/edit/RecordSet-Edit.js +1 -0
- package/source/views/list/RecordSet-List-HeaderList.js +1 -0
- package/source/views/list/RecordSet-List-PaginationBottom.js +1 -0
- package/source/views/list/RecordSet-List-PaginationTop.js +1 -0
- package/source/views/list/RecordSet-List-RecordList.js +1 -0
- package/source/views/list/RecordSet-List-RecordListEntry.js +1 -0
- package/source/views/list/RecordSet-List-RecordListHeader.js +1 -0
- package/source/views/list/RecordSet-List-Title.js +1 -0
- package/source/views/list/RecordSet-List.js +12 -34
- package/source/views/read/RecordSet-Read-HeaderRead.js +1 -0
- package/source/views/read/RecordSet-Read-RecordRead.js +1 -0
- package/source/views/read/RecordSet-Read-RecordReadExtra.js +1 -0
- package/source/views/read/RecordSet-Read-TabBarRead.js +1 -0
- package/source/views/read/RecordSet-Read.js +1 -0
- package/types/Pict-Section-RecordSet.d.ts +1 -3
- package/types/application/Pict-Application-RecordSet.d.ts +1 -7
- package/types/application/Pict-Application-RecordSet.d.ts.map +1 -1
- package/types/providers/RecordSet-Link-Manager.d.ts +2 -5
- package/types/providers/RecordSet-Link-Manager.d.ts.map +1 -1
- package/types/providers/RecordSet-RecordProvider-Base.d.ts +19 -0
- package/types/providers/RecordSet-RecordProvider-Base.d.ts.map +1 -1
- package/types/providers/RecordSet-RecordProvider-MeadowEndpoints.d.ts +38 -5
- package/types/providers/RecordSet-RecordProvider-MeadowEndpoints.d.ts.map +1 -1
- package/types/providers/RecordSet-Router.d.ts +3 -8
- package/types/providers/RecordSet-Router.d.ts.map +1 -1
- package/types/services/RecordsSet-MetaController.d.ts +20 -4
- package/types/services/RecordsSet-MetaController.d.ts.map +1 -1
- package/types/templates/Pict-Template-FilterView.d.ts +18 -0
- package/types/templates/Pict-Template-FilterView.d.ts.map +1 -0
- package/types/views/RecordSet-Filter.d.ts +30 -27
- package/types/views/RecordSet-Filter.d.ts.map +1 -1
- package/types/views/RecordSet-RecordBaseView.d.ts +3 -28
- package/types/views/RecordSet-RecordBaseView.d.ts.map +1 -1
- package/types/views/RecordsSet-MacroView.d.ts +2 -25
- package/types/views/RecordsSet-MacroView.d.ts.map +1 -1
- package/types/views/dashboard/RecordSet-Dashboard-HeaderDashboard.d.ts +6 -29
- package/types/views/dashboard/RecordSet-Dashboard-HeaderDashboard.d.ts.map +1 -1
- package/types/views/dashboard/RecordSet-Dashboard-PaginationBottom.d.ts +11 -0
- package/types/views/dashboard/RecordSet-Dashboard-PaginationBottom.d.ts.map +1 -0
- package/types/views/dashboard/RecordSet-Dashboard-PaginationTop.d.ts +11 -0
- package/types/views/dashboard/RecordSet-Dashboard-PaginationTop.d.ts.map +1 -0
- package/types/views/dashboard/RecordSet-Dashboard-RecordList.d.ts +11 -0
- package/types/views/dashboard/RecordSet-Dashboard-RecordList.d.ts.map +1 -0
- package/types/views/dashboard/RecordSet-Dashboard-RecordListEntry.d.ts +11 -0
- package/types/views/dashboard/RecordSet-Dashboard-RecordListEntry.d.ts.map +1 -0
- package/types/views/dashboard/RecordSet-Dashboard-RecordListHeader.d.ts +11 -0
- package/types/views/dashboard/RecordSet-Dashboard-RecordListHeader.d.ts.map +1 -0
- package/types/views/dashboard/RecordSet-Dashboard-RecordSetDashboard.d.ts +2 -25
- package/types/views/dashboard/RecordSet-Dashboard-RecordSetDashboard.d.ts.map +1 -1
- package/types/views/dashboard/RecordSet-Dashboard-TabBarDashboard.d.ts +2 -25
- package/types/views/dashboard/RecordSet-Dashboard-TabBarDashboard.d.ts.map +1 -1
- package/types/views/dashboard/RecordSet-Dashboard-Title.d.ts +11 -0
- package/types/views/dashboard/RecordSet-Dashboard-Title.d.ts.map +1 -0
- package/types/views/dashboard/RecordSet-Dashboard.d.ts +20 -25
- package/types/views/dashboard/RecordSet-Dashboard.d.ts.map +1 -1
- package/types/views/edit/RecordSet-Edit-HeaderEdit.d.ts +2 -25
- package/types/views/edit/RecordSet-Edit-HeaderEdit.d.ts.map +1 -1
- package/types/views/edit/RecordSet-Edit-RecordEdit.d.ts +2 -25
- package/types/views/edit/RecordSet-Edit-RecordEdit.d.ts.map +1 -1
- package/types/views/edit/RecordSet-Edit-RecordEditControls.d.ts +2 -25
- package/types/views/edit/RecordSet-Edit-RecordEditControls.d.ts.map +1 -1
- package/types/views/edit/RecordSet-Edit-RecordEditExtra.d.ts +2 -25
- package/types/views/edit/RecordSet-Edit-RecordEditExtra.d.ts.map +1 -1
- package/types/views/edit/RecordSet-Edit-TabBarEdit.d.ts +2 -25
- package/types/views/edit/RecordSet-Edit-TabBarEdit.d.ts.map +1 -1
- package/types/views/edit/RecordSet-Edit.d.ts +2 -25
- package/types/views/edit/RecordSet-Edit.d.ts.map +1 -1
- package/types/views/list/RecordSet-List-HeaderList.d.ts +2 -25
- package/types/views/list/RecordSet-List-HeaderList.d.ts.map +1 -1
- package/types/views/list/RecordSet-List-PaginationBottom.d.ts +2 -25
- package/types/views/list/RecordSet-List-PaginationBottom.d.ts.map +1 -1
- package/types/views/list/RecordSet-List-PaginationTop.d.ts +2 -25
- package/types/views/list/RecordSet-List-PaginationTop.d.ts.map +1 -1
- package/types/views/list/RecordSet-List-RecordList.d.ts +2 -25
- package/types/views/list/RecordSet-List-RecordList.d.ts.map +1 -1
- package/types/views/list/RecordSet-List-RecordListEntry.d.ts +2 -25
- package/types/views/list/RecordSet-List-RecordListEntry.d.ts.map +1 -1
- package/types/views/list/RecordSet-List-RecordListHeader.d.ts +2 -25
- package/types/views/list/RecordSet-List-RecordListHeader.d.ts.map +1 -1
- package/types/views/list/RecordSet-List-Title.d.ts +2 -25
- package/types/views/list/RecordSet-List-Title.d.ts.map +1 -1
- package/types/views/list/RecordSet-List.d.ts +2 -26
- package/types/views/list/RecordSet-List.d.ts.map +1 -1
- package/types/views/read/RecordSet-Read-HeaderRead.d.ts +2 -25
- package/types/views/read/RecordSet-Read-HeaderRead.d.ts.map +1 -1
- package/types/views/read/RecordSet-Read-RecordRead.d.ts +2 -25
- package/types/views/read/RecordSet-Read-RecordRead.d.ts.map +1 -1
- package/types/views/read/RecordSet-Read-RecordReadExtra.d.ts +2 -25
- package/types/views/read/RecordSet-Read-RecordReadExtra.d.ts.map +1 -1
- package/types/views/read/RecordSet-Read-TabBarRead.d.ts +2 -25
- package/types/views/read/RecordSet-Read-TabBarRead.d.ts.map +1 -1
- package/types/views/read/RecordSet-Read.d.ts +2 -25
- package/types/views/read/RecordSet-Read.d.ts.map +1 -1
- package/source/views/dashboard/RecordSet-Dashboard-RecordSetDashboard.js +0 -63
|
@@ -12,6 +12,71 @@ module.exports.default_configuration.pict_configuration = (
|
|
|
12
12
|
"AutoRenderMainViewportViewAfterInitialize": false
|
|
13
13
|
},
|
|
14
14
|
|
|
15
|
+
"DefaultDashboards":
|
|
16
|
+
[
|
|
17
|
+
{
|
|
18
|
+
"Scope": "Bookstore",
|
|
19
|
+
"CoreEntity": "Book",
|
|
20
|
+
"RecordDecorationConfiguration":
|
|
21
|
+
[
|
|
22
|
+
{
|
|
23
|
+
"Entity": "BookAuthorJoin",
|
|
24
|
+
"Filter": "FBL~IDBook~INN~{~PJU:,^IDBook^Record.State.CoreEntityRecordSubset~}",
|
|
25
|
+
"Destination": "State.BookAuthorJoins"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"Entity": "Author",
|
|
29
|
+
"Filter": "FBL~IDAuthor~INN~{~PJU:,^IDAuthor^Record.State.BookAuthorJoins~}",
|
|
30
|
+
"Destination": "State.Authors"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"Type": "MapJoin",
|
|
34
|
+
"DestinationRecordSetAddress": "State.CoreEntityRecordSubset",
|
|
35
|
+
"DestinationJoinValue": "IDBook",
|
|
36
|
+
"JoinJoinValueLHS": "IDBook",
|
|
37
|
+
"Joins": "State.BookAuthorJoins",
|
|
38
|
+
"JoinJoinValueRHS": "IDAuthor",
|
|
39
|
+
"JoinRecordSetAddress": "State.Authors",
|
|
40
|
+
"JoinValue": "IDAuthor",
|
|
41
|
+
"RecordDestinationAddress": "Authors"
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"Descriptors":
|
|
45
|
+
{
|
|
46
|
+
"Title":
|
|
47
|
+
{
|
|
48
|
+
"Name": "Title",
|
|
49
|
+
"Hash": "Title",
|
|
50
|
+
"DataType": "String"
|
|
51
|
+
},
|
|
52
|
+
"Authors":
|
|
53
|
+
{
|
|
54
|
+
"Name": "Authors",
|
|
55
|
+
"Hash": "Authors",
|
|
56
|
+
"PictForm":
|
|
57
|
+
{
|
|
58
|
+
"InputType": "ReadOnly",
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"AuthorCount":
|
|
62
|
+
{
|
|
63
|
+
"Name": "Number of Authors",
|
|
64
|
+
"Hash": "AuthorCount",
|
|
65
|
+
"DataType": "Number",
|
|
66
|
+
"PictForm":
|
|
67
|
+
{
|
|
68
|
+
"InputType": "ReadOnly"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"Scope": "AuthorSummary",
|
|
75
|
+
"Descriptors":
|
|
76
|
+
{
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
],
|
|
15
80
|
"DefaultRecordSetConfigurations":
|
|
16
81
|
[
|
|
17
82
|
{
|
|
@@ -38,8 +103,56 @@ module.exports.default_configuration.pict_configuration = (
|
|
|
38
103
|
"RecordSetListHasExtraColumns": true,
|
|
39
104
|
"RecordSetListExtraColumnsHeaderTemplate": "<th style=\"border-bottom: 1px solid #ccc; padding: 5px; background-color: #f2f2f2; color: #333;\">Cover</th>",
|
|
40
105
|
"RecordSetListExtraColumnRowTemplate": "<td><img src=\"{~D:Record.Data.ImageURL~}\"></td>",
|
|
106
|
+
|
|
107
|
+
"SearchFields": [ "Title" ],
|
|
108
|
+
|
|
109
|
+
"RecordSetFilterURLTemplate-Default": "/PSRS/{~D:Record.RecordSet~}/ListFilteredTo/{~D:Record.FilterString~}",
|
|
110
|
+
"RecordSetFilterURLTemplate-List": "/PSRS/{~D:Record.RecordSet~}/ListFilteredTo/{~D:Record.FilterString~}",
|
|
111
|
+
"RecordSetFilterURLTemplate-Dashboard": "/PSRS/{~D:Record.RecordSet~}/DashboardFilteredTo/{~D:Record.FilterString~}",
|
|
112
|
+
|
|
113
|
+
"RecordSetURLPrefix": "/1.0/"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"RecordSet": "BookstoreInventory",
|
|
117
|
+
|
|
118
|
+
"RecordSetType": "MeadowEndpoint", // Could be "Custom" which would require a provider to already be created for the record set.
|
|
119
|
+
"RecordSetMeadowEntity": "Book", // This leverages the /Schema endpoint to get the record set columns.
|
|
120
|
+
"RecordDecorationConfiguration":
|
|
121
|
+
[
|
|
122
|
+
{
|
|
123
|
+
"Entity": "BookAuthorJoin",
|
|
124
|
+
"Filter": "FBL~IDBook~INN~{~PJU:,^IDBook^Record.State.CoreEntityRecordSubset~}",
|
|
125
|
+
"Destination": "State.BookAuthorJoins"
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"Entity": "Author",
|
|
129
|
+
"Filter": "FBL~IDAuthor~INN~{~PJU:,^IDAuthor^Record.State.BookAuthorJoins~}",
|
|
130
|
+
"Destination": "State.Authors"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"Type": "MapJoin",
|
|
134
|
+
"DestinationRecordSetAddress": "State.CoreEntityRecordSubset",
|
|
135
|
+
"DestinationJoinValue": "IDBook",
|
|
136
|
+
"JoinJoinValueLHS": "IDBook",
|
|
137
|
+
"Joins": "State.BookAuthorJoins",
|
|
138
|
+
"JoinJoinValueRHS": "IDAuthor",
|
|
139
|
+
"JoinRecordSetAddress": "State.Authors",
|
|
140
|
+
"JoinValue": "IDAuthor",
|
|
141
|
+
"RecordDestinationAddress": "Authors"
|
|
142
|
+
}
|
|
143
|
+
],
|
|
144
|
+
"AvailableVerbs": [ "Dashboard" ],
|
|
145
|
+
|
|
146
|
+
"RecordSetListHasExtraColumns": true,
|
|
147
|
+
"RecordSetListExtraColumnsHeaderTemplate": "<th style=\"border-bottom: 1px solid #ccc; padding: 5px; background-color: #f2f2f2; color: #333;\">Cover</th>",
|
|
148
|
+
"RecordSetListExtraColumnRowTemplate": "<td><img src=\"{~D:Record.Data.ImageURL~}\"></td>",
|
|
149
|
+
|
|
41
150
|
"SearchFields": [ "Title" ],
|
|
42
151
|
|
|
152
|
+
"RecordSetFilterURLTemplate-Default": "/PSRS/{~D:Record.RecordSet~}/ListFilteredTo/{~D:Record.FilterString~}",
|
|
153
|
+
"RecordSetFilterURLTemplate-List": "/PSRS/{~D:Record.RecordSet~}/ListFilteredTo/{~D:Record.FilterString~}",
|
|
154
|
+
"RecordSetFilterURLTemplate-Dashboard": "/PSRS/{~D:Record.RecordSet~}/DashboardFilteredTo/{~D:Record.FilterString~}",
|
|
155
|
+
|
|
43
156
|
"RecordSetURLPrefix": "/1.0/"
|
|
44
157
|
},
|
|
45
158
|
{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pict-section-recordset",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.16",
|
|
4
4
|
"description": "Pict dynamic record set management views",
|
|
5
5
|
"main": "source/Pict-Section-RecordSet.js",
|
|
6
6
|
"directories": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"browser-env": "^3.3.0",
|
|
34
34
|
"eslint": "^9.27.0",
|
|
35
35
|
"jquery": "^3.7.1",
|
|
36
|
-
"pict": "^1.0.
|
|
36
|
+
"pict": "^1.0.262",
|
|
37
37
|
"pict-application": "^1.0.25",
|
|
38
38
|
"pict-service-commandlineutility": "^1.0.15",
|
|
39
39
|
"quackage": "^1.0.41",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"fable-serviceproviderbase": "^3.0.15",
|
|
44
44
|
"pict-provider": "^1.0.3",
|
|
45
45
|
"pict-router": "^1.0.3",
|
|
46
|
-
"pict-section-form": "^1.0.
|
|
46
|
+
"pict-section-form": "^1.0.97",
|
|
47
47
|
"pict-template": "^1.0.10",
|
|
48
48
|
"pict-view": "^1.0.60"
|
|
49
49
|
},
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const libPictProvider = require('pict-provider');
|
|
2
2
|
|
|
3
|
+
/** @type {Record<string, any>} */
|
|
3
4
|
const _DEFAULT_PROVIDER_CONFIGURATION =
|
|
4
5
|
{
|
|
5
6
|
ProviderIdentifier: 'Pict-RecordSet-LinkManager',
|
|
@@ -49,4 +50,4 @@ class PictRecordSetRouter extends libPictProvider
|
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
module.exports = PictRecordSetRouter;
|
|
52
|
-
module.exports.default_configuration = _DEFAULT_PROVIDER_CONFIGURATION;
|
|
53
|
+
module.exports.default_configuration = _DEFAULT_PROVIDER_CONFIGURATION;
|
|
@@ -104,6 +104,20 @@ class RecordSetProviderBase extends libPictProvider
|
|
|
104
104
|
return { Records: [], Facets: { } };
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
+
/**
|
|
108
|
+
* Read records from the provider.
|
|
109
|
+
*
|
|
110
|
+
* @param {RecordSetFilter} pOptions - Options for the read operation.
|
|
111
|
+
*
|
|
112
|
+
* @return {Promise<RecordSetResult>} - The result of the read operation.
|
|
113
|
+
*/
|
|
114
|
+
async getDecoratedRecords(pOptions)
|
|
115
|
+
{
|
|
116
|
+
const tmpRecords = await this.getRecords(pOptions);
|
|
117
|
+
await this.decorateCoreRecords(tmpRecords.Records);
|
|
118
|
+
return tmpRecords;
|
|
119
|
+
}
|
|
120
|
+
|
|
107
121
|
/**
|
|
108
122
|
* Read records from the provider.
|
|
109
123
|
*
|
|
@@ -133,6 +147,7 @@ class RecordSetProviderBase extends libPictProvider
|
|
|
133
147
|
* Create a new record.
|
|
134
148
|
*
|
|
135
149
|
* @param {Record<string, any>} pRecord - The record to create.
|
|
150
|
+
* @return {Promise<Record<string, any>>} - The created record.
|
|
136
151
|
*/
|
|
137
152
|
async createRecord(pRecord)
|
|
138
153
|
{
|
|
@@ -144,6 +159,7 @@ class RecordSetProviderBase extends libPictProvider
|
|
|
144
159
|
* Update a record.
|
|
145
160
|
*
|
|
146
161
|
* @param {Record<string, any>} pRecord - The record to update.
|
|
162
|
+
* @return {Promise<Record<string, any>>} - The updated record.
|
|
147
163
|
*/
|
|
148
164
|
async updateRecord(pRecord)
|
|
149
165
|
{
|
|
@@ -155,6 +171,7 @@ class RecordSetProviderBase extends libPictProvider
|
|
|
155
171
|
* Delete a record.
|
|
156
172
|
*
|
|
157
173
|
* @param {Record<string, any>} pRecord - The record to delete.
|
|
174
|
+
* @return {Promise<void>}
|
|
158
175
|
*/
|
|
159
176
|
async deleteRecord(pRecord)
|
|
160
177
|
{
|
|
@@ -188,6 +205,7 @@ class RecordSetProviderBase extends libPictProvider
|
|
|
188
205
|
* Clone a record.
|
|
189
206
|
*
|
|
190
207
|
* @param {Record<string, any>} pRecord - The record to clone.
|
|
208
|
+
* @return {Promise<Record<string, any>>} - The cloned record.
|
|
191
209
|
*/
|
|
192
210
|
async cloneRecord(pRecord)
|
|
193
211
|
{
|
|
@@ -211,6 +229,16 @@ class RecordSetProviderBase extends libPictProvider
|
|
|
211
229
|
{
|
|
212
230
|
return { };
|
|
213
231
|
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Abstract decoration method for core records. Subclasses should implement this method to decorate records with additional information.
|
|
235
|
+
*
|
|
236
|
+
* @param {Array<Record<string, any>>} pRecords - The records to decorate.
|
|
237
|
+
* @return {Promise<void>}
|
|
238
|
+
*/
|
|
239
|
+
async decorateCoreRecords(pRecords)
|
|
240
|
+
{
|
|
241
|
+
}
|
|
214
242
|
}
|
|
215
243
|
|
|
216
244
|
module.exports = RecordSetProviderBase;
|
|
@@ -10,7 +10,7 @@ const libRecordSetProviderBase = require('./RecordSet-RecordProvider-Base.js');
|
|
|
10
10
|
* Class representing a data change detection provider for Pict dynamic forms.
|
|
11
11
|
* @extends libRecordSetProviderBase
|
|
12
12
|
*/
|
|
13
|
-
class
|
|
13
|
+
class MeadowEndpointsRecordSetProvider extends libRecordSetProviderBase
|
|
14
14
|
{
|
|
15
15
|
/**
|
|
16
16
|
* Creates an instance of RecordSetProvider.
|
|
@@ -26,8 +26,21 @@ class RecordSetProvider extends libRecordSetProviderBase
|
|
|
26
26
|
this.options;
|
|
27
27
|
/** @type {import('fable')} */
|
|
28
28
|
this.fable;
|
|
29
|
-
/** @type {import('
|
|
29
|
+
/** @type {import('pict') & {
|
|
30
|
+
* log: any,
|
|
31
|
+
* services:
|
|
32
|
+
* {
|
|
33
|
+
* PictSectionRecordSet: InstanceType<import('../Pict-Section-RecordSet.js')>,
|
|
34
|
+
* [key: string]: any,
|
|
35
|
+
* },
|
|
36
|
+
* instantiateServiceProviderWithoutRegistration: (hash: String) => any,
|
|
37
|
+
* PictSectionRecordSet: InstanceType<import('../Pict-Section-RecordSet.js')>
|
|
38
|
+
* }} */
|
|
30
39
|
this.pict;
|
|
40
|
+
/** @type {string} */
|
|
41
|
+
this.Hash;
|
|
42
|
+
/** @type {string} */
|
|
43
|
+
this.UUID;
|
|
31
44
|
//TODO: make this typedef better
|
|
32
45
|
/** @type {Record<string, any>} */
|
|
33
46
|
this._Schema = { };
|
|
@@ -359,6 +372,43 @@ class RecordSetProvider extends libRecordSetProviderBase
|
|
|
359
372
|
}
|
|
360
373
|
return this._Schema;
|
|
361
374
|
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Abstract decoration method for core records. Subclasses should implement this method to decorate records with additional information.
|
|
378
|
+
*
|
|
379
|
+
* @param {Array<Record<string, any>>} pRecords - The records to decorate.
|
|
380
|
+
* @return {Promise<void>}
|
|
381
|
+
*/
|
|
382
|
+
async decorateCoreRecords(pRecords)
|
|
383
|
+
{
|
|
384
|
+
if (!this.options.RecordDecorationConfiguration)
|
|
385
|
+
{
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
if (!Array.isArray(this.options.RecordDecorationConfiguration))
|
|
389
|
+
{
|
|
390
|
+
this.pict.log.error('RecordDecorationConfiguration is not an array', { RecordDecorationConfiguration: this.options.RecordDecorationConfiguration });
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
this.pict.AppData[this.Hash] = { CoreEntityRecordSubset: pRecords };
|
|
394
|
+
const config = [{ Type: 'SetStateAddress', StateAddress: `AppData[${this.Hash}]` }].concat(this.options.RecordDecorationConfiguration);
|
|
395
|
+
|
|
396
|
+
try
|
|
397
|
+
{
|
|
398
|
+
await new Promise((resolve, reject) => this.pict.EntityProvider.gatherDataFromServer(config, (err) =>
|
|
399
|
+
{
|
|
400
|
+
if (err)
|
|
401
|
+
{
|
|
402
|
+
return reject(err);
|
|
403
|
+
}
|
|
404
|
+
resolve();
|
|
405
|
+
}));
|
|
406
|
+
}
|
|
407
|
+
catch (error)
|
|
408
|
+
{
|
|
409
|
+
this.pict.log.error(`MeadowEndpointsRecordSetProvider: Error gathering data from server for record decoration: ${error.message}`, { Stack: error.stack });
|
|
410
|
+
}
|
|
411
|
+
}
|
|
362
412
|
}
|
|
363
413
|
|
|
364
|
-
module.exports =
|
|
414
|
+
module.exports = MeadowEndpointsRecordSetProvider;
|
|
@@ -13,6 +13,7 @@ const providerLinkManager = require('../providers/RecordSet-Link-Manager.js');
|
|
|
13
13
|
|
|
14
14
|
const providerRouter = require('../providers/RecordSet-Router.js');
|
|
15
15
|
|
|
16
|
+
/** @type {Record<string, any>} */
|
|
16
17
|
const _DEFAULT_CONFIGURATION =
|
|
17
18
|
{
|
|
18
19
|
DefaultMeadowURLPrefix: '/1.0/'
|
|
@@ -27,6 +28,7 @@ class RecordSetMetacontroller extends libFableServiceProviderBase
|
|
|
27
28
|
|
|
28
29
|
/** @type {import('pict') & { addAndInstantiateSingletonService: (hash: string, options: any, prototype: any) => any }} */
|
|
29
30
|
this.fable;
|
|
31
|
+
this.pict = this.fable;
|
|
30
32
|
/** @type {any} */
|
|
31
33
|
this.log;
|
|
32
34
|
/** @type {any} */
|
|
@@ -44,7 +46,8 @@ class RecordSetMetacontroller extends libFableServiceProviderBase
|
|
|
44
46
|
this.recordSetProviders = {};
|
|
45
47
|
this.recordSetProviderConfigurations = {};
|
|
46
48
|
|
|
47
|
-
this.
|
|
49
|
+
this.dashboardConfigurations = {};
|
|
50
|
+
|
|
48
51
|
this.sessionProviders = [];
|
|
49
52
|
|
|
50
53
|
this.has_initialized = false;
|
|
@@ -76,6 +79,15 @@ class RecordSetMetacontroller extends libFableServiceProviderBase
|
|
|
76
79
|
}
|
|
77
80
|
]
|
|
78
81
|
*/
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @return {Record<string, any>} - The registered configuration for the RecordSet
|
|
85
|
+
*/
|
|
86
|
+
getRecordSetConfiguration(pRecordSet)
|
|
87
|
+
{
|
|
88
|
+
return this.recordSetProviderConfigurations[pRecordSet];
|
|
89
|
+
}
|
|
90
|
+
|
|
79
91
|
loadRecordSetConfiguration(pRecordSetConfiguration)
|
|
80
92
|
{
|
|
81
93
|
if (typeof pRecordSetConfiguration !== 'object')
|
|
@@ -189,6 +201,72 @@ class RecordSetMetacontroller extends libFableServiceProviderBase
|
|
|
189
201
|
}
|
|
190
202
|
}
|
|
191
203
|
|
|
204
|
+
/**
|
|
205
|
+
* @param {Array<Record<string, any>>} pDashboardConfigurationArray - An array of dashboard configurations.
|
|
206
|
+
*/
|
|
207
|
+
loadDashboardConfigurationArray(pDashboardConfigurationArray)
|
|
208
|
+
{
|
|
209
|
+
if (!Array.isArray(pDashboardConfigurationArray))
|
|
210
|
+
{
|
|
211
|
+
this.fable.log.error(`RecordSetMetacontroller: ${this.UUID} loadDashboardConfigurationArray called with invalid configuration.`);
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
if (pDashboardConfigurationArray.length === 0)
|
|
215
|
+
{
|
|
216
|
+
this.fable.log.warn(`RecordSetMetacontroller: ${this.UUID} loadDashboardConfigurationArray called with empty configuration.`);
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
for (const tmpDashboardConfiguration of pDashboardConfigurationArray)
|
|
220
|
+
{
|
|
221
|
+
if (tmpDashboardConfiguration.RecordDecorationConfiguration)
|
|
222
|
+
{
|
|
223
|
+
//TODO: register the record decoration configuration
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* TODO: This method is still incomplete.
|
|
230
|
+
*
|
|
231
|
+
* @param {Record<string, any>} pDashboardConfiguration - The dashboard configuration to add.
|
|
232
|
+
*/
|
|
233
|
+
addDashboardConfiguration(pDashboardConfiguration)
|
|
234
|
+
{
|
|
235
|
+
let tmpProvider = false;
|
|
236
|
+
|
|
237
|
+
if (this.recordSetProviders[pDashboardConfiguration.RecordSet])
|
|
238
|
+
{
|
|
239
|
+
this.pict.log.error(`RecordSetMetacontroller: ${this.UUID} addDashboardConfiguration called with invalid configuration. RecordSet ${pDashboardConfiguration.RecordSet} already exists.`);
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
const providerConfiguration = Object.assign({}, {Hash: `RSP-Provider-${pDashboardConfiguration.RecordSet}`}, pDashboardConfiguration);
|
|
243
|
+
this.dashboardConfigurations[providerConfiguration.RecordSet] = providerConfiguration;
|
|
244
|
+
|
|
245
|
+
// Create a Meadow Endpoints provider
|
|
246
|
+
// Allow the Record Set to optionally point to a different entity
|
|
247
|
+
if ('RecordSetCoreMeadowEntity' in pDashboardConfiguration)
|
|
248
|
+
{
|
|
249
|
+
providerConfiguration.Entity = pDashboardConfiguration.RecordSetCoreMeadowEntity;
|
|
250
|
+
}
|
|
251
|
+
else
|
|
252
|
+
{
|
|
253
|
+
this.pict.log.error(`RecordSetMetacontroller: ${this.UUID} addDashboardConfiguration called with invalid configuration. Missing RecordSetCoreMeadowEntity.`);
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
// Default the URLPrefix to the base URLPrefix
|
|
257
|
+
if ('RecordSetURLPrefix' in pDashboardConfiguration)
|
|
258
|
+
{
|
|
259
|
+
providerConfiguration.URLPrefix = pDashboardConfiguration.RecordSetURLPrefix;
|
|
260
|
+
}
|
|
261
|
+
else
|
|
262
|
+
{
|
|
263
|
+
providerConfiguration.URLPrefix = '/1.0/';
|
|
264
|
+
}
|
|
265
|
+
tmpProvider = this.recordSetProviders[pDashboardConfiguration.RecordSet] = this.fable.addProvider(providerConfiguration.Hash, providerConfiguration, providerMeadowEndpoints);
|
|
266
|
+
|
|
267
|
+
return tmpProvider;
|
|
268
|
+
}
|
|
269
|
+
|
|
192
270
|
loadRecordSetDynamcally(pRecordSet, pEntity, pDefaultFilter)
|
|
193
271
|
{
|
|
194
272
|
if (typeof(pRecordSet) === 'object')
|
|
@@ -283,6 +361,7 @@ class RecordSetMetacontroller extends libFableServiceProviderBase
|
|
|
283
361
|
this.fable.addProvider('RecordSetLinkManager', {}, providerLinkManager);
|
|
284
362
|
|
|
285
363
|
// Add the subviews internally and externally
|
|
364
|
+
this.pict.addTemplate(require('../templates/Pict-Template-FilterView.js'));
|
|
286
365
|
this.childViews.list = this.fable.addView('RSP-RecordSet-List', this.options, viewRecordSetList);
|
|
287
366
|
this.childViews.edit = this.fable.addView('RSP-RecordSet-Edit', this.options, viewRecordSetEdit);
|
|
288
367
|
this.childViews.read = this.fable.addView('RSP-RecordSet-Read', this.options, viewRecordSetRead);
|
|
@@ -301,6 +380,11 @@ class RecordSetMetacontroller extends libFableServiceProviderBase
|
|
|
301
380
|
this.loadRecordSetConfigurationArray(this.fable.settings.DefaultRecordSetConfigurations);
|
|
302
381
|
}
|
|
303
382
|
|
|
383
|
+
if (this.fable.settings.hasOwnProperty('DefaultDashboards'))
|
|
384
|
+
{
|
|
385
|
+
this.loadDashboardConfigurationArray(this.fable.settings.DefaultDashboards);
|
|
386
|
+
}
|
|
387
|
+
|
|
304
388
|
this.has_initialized = true;
|
|
305
389
|
|
|
306
390
|
// Load pict-router if it isn't loaded
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
const libPictTemplate = require('pict-template');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Specialized instruction for rendering the filter view and plumbing in required context.
|
|
5
|
+
*
|
|
6
|
+
* Based on the Pict base {~V:...~} template instruction.
|
|
7
|
+
*/
|
|
8
|
+
class PictTemplateFilterViewInstruction extends libPictTemplate
|
|
9
|
+
{
|
|
10
|
+
/**
|
|
11
|
+
* @param {Object} pFable - The Fable Framework instance
|
|
12
|
+
* @param {Object} pOptions - The options for the service
|
|
13
|
+
* @param {String} pServiceHash - The hash of the service
|
|
14
|
+
*/
|
|
15
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
16
|
+
{
|
|
17
|
+
super(pFable, pOptions, pServiceHash);
|
|
18
|
+
|
|
19
|
+
/** @type {any} */
|
|
20
|
+
this.log;
|
|
21
|
+
|
|
22
|
+
this.addPattern('{~FV:', '~}');
|
|
23
|
+
this.addPattern('{~FilterView:', '~}');
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
if (!('__TemplateOutputCache' in this.pict))
|
|
27
|
+
{
|
|
28
|
+
this.pict.__TemplateOutputCache = {};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Render a template expression, returning a string with the resulting content.
|
|
34
|
+
*
|
|
35
|
+
* @param {string} pTemplateHash - The hash contents of the template (what's between the template start and stop tags)
|
|
36
|
+
* @param {any} pRecord - The json object to be used as the Record for the template render
|
|
37
|
+
* @param {Array<any>} pContextArray - An array of context objects accessible from the template; safe to leave empty
|
|
38
|
+
*
|
|
39
|
+
* @return {string} The rendered template
|
|
40
|
+
*/
|
|
41
|
+
render(pTemplateHash, pRecord, pContextArray)
|
|
42
|
+
{
|
|
43
|
+
let [ tmpViewHash, tmpViewContext ] = pTemplateHash.split(':');
|
|
44
|
+
tmpViewHash = tmpViewHash.trim();
|
|
45
|
+
const tmpRecordSet = pRecord.RecordSet || '';
|
|
46
|
+
if (!tmpRecordSet)
|
|
47
|
+
{
|
|
48
|
+
this.pict.log.error(`Pict: Filter View Template Render: No record set specified in template hash [${pTemplateHash}] for view [${tmpViewHash}]`);
|
|
49
|
+
return '';
|
|
50
|
+
}
|
|
51
|
+
const tmpRecordSetConfiguration = this.pict.PictSectionRecordSet.recordSetProviderConfigurations?.[tmpRecordSet];
|
|
52
|
+
if (!tmpRecordSetConfiguration)
|
|
53
|
+
{
|
|
54
|
+
this.pict.log.error(`Pict: Filter View Template Render: No record set configuration found for [${tmpRecordSet}] in template hash [${pTemplateHash}] for view [${tmpViewHash}]`);
|
|
55
|
+
return '';
|
|
56
|
+
}
|
|
57
|
+
if (tmpViewContext)
|
|
58
|
+
{
|
|
59
|
+
tmpViewContext = tmpViewContext.trim();
|
|
60
|
+
}
|
|
61
|
+
else
|
|
62
|
+
{
|
|
63
|
+
tmpViewContext = 'Default';
|
|
64
|
+
}
|
|
65
|
+
if (!(tmpViewHash in this.pict.views))
|
|
66
|
+
{
|
|
67
|
+
this.log.warn(`Pict: Filter View Template Render: View not found for [${tmpViewHash}]`);
|
|
68
|
+
return '';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
pRecord = pRecord || {};
|
|
72
|
+
if (!pRecord.RecordSet)
|
|
73
|
+
{
|
|
74
|
+
pRecord.RecordSet = tmpRecordSet;
|
|
75
|
+
}
|
|
76
|
+
if (!pRecord.RecordSetConfiguration)
|
|
77
|
+
{
|
|
78
|
+
pRecord.RecordSetConfiguration = tmpRecordSetConfiguration;
|
|
79
|
+
}
|
|
80
|
+
if (!pRecord.ViewContext)
|
|
81
|
+
{
|
|
82
|
+
pRecord.ViewContext = tmpViewContext;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
let tmpRenderGUID = this.pict.getUUID();
|
|
86
|
+
|
|
87
|
+
/** @type {import('pict-view')} */
|
|
88
|
+
const tmpView = this.pict.views[tmpViewHash];
|
|
89
|
+
|
|
90
|
+
tmpView.render('__Virtual', `__TemplateOutputCache.${tmpRenderGUID}`, pRecord);
|
|
91
|
+
|
|
92
|
+
let tmpResult = this.pict.__TemplateOutputCache[tmpRenderGUID];
|
|
93
|
+
// TODO: Uncomment this when we like how it's working
|
|
94
|
+
//delete this.pict.__TemplateOutputCache[tmpRenderGUID];
|
|
95
|
+
|
|
96
|
+
return tmpResult;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* @param {string} pTemplateHash - The hash contents of the template (what's between the template start and stop tags)
|
|
101
|
+
* @param {any} pRecord - The json object to be used as the Record for the template
|
|
102
|
+
* @param {(pError?: Error, pResult?: string) => void} fCallback - The callback function to call with the result
|
|
103
|
+
* @param {Array<any>} pContextArray - An array of context objects accessible from the template; safe to leave empty
|
|
104
|
+
* @return {void}
|
|
105
|
+
*/
|
|
106
|
+
renderAsync(pTemplateHash, pRecord, fCallback, pContextArray)
|
|
107
|
+
{
|
|
108
|
+
let [ tmpViewHash, tmpViewContext ] = pTemplateHash.split(':');
|
|
109
|
+
tmpViewHash = tmpViewHash.trim();
|
|
110
|
+
const tmpRecordSet = pRecord.RecordSet || '';
|
|
111
|
+
if (!tmpRecordSet)
|
|
112
|
+
{
|
|
113
|
+
this.pict.log.error(`Pict: Filter View Template Render: No record set specified in template hash [${pTemplateHash}] for view [${tmpViewHash}]`);
|
|
114
|
+
return fCallback(null, '');
|
|
115
|
+
}
|
|
116
|
+
const tmpRecordSetConfiguration = this.pict.PictSectionRecordSet.recordSetProviderConfigurations?.[tmpRecordSet];
|
|
117
|
+
if (!tmpRecordSetConfiguration)
|
|
118
|
+
{
|
|
119
|
+
this.pict.log.error(`Pict: Filter View Template Render: No record set configuration found for [${tmpRecordSet}] in template hash [${pTemplateHash}] for view [${tmpViewHash}]`);
|
|
120
|
+
return fCallback(null, '');
|
|
121
|
+
}
|
|
122
|
+
if (tmpViewContext)
|
|
123
|
+
{
|
|
124
|
+
tmpViewContext = tmpViewContext.trim();
|
|
125
|
+
}
|
|
126
|
+
else
|
|
127
|
+
{
|
|
128
|
+
tmpViewContext = 'Default';
|
|
129
|
+
}
|
|
130
|
+
if (!(tmpViewHash in this.pict.views))
|
|
131
|
+
{
|
|
132
|
+
this.log.warn(`Pict: Filter View Template Render: View not found for [${tmpViewHash}]`);
|
|
133
|
+
return fCallback(null, '');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
pRecord = pRecord || {};
|
|
137
|
+
if (!pRecord.RecordSet)
|
|
138
|
+
{
|
|
139
|
+
pRecord.RecordSet = tmpRecordSet;
|
|
140
|
+
}
|
|
141
|
+
if (!pRecord.RecordSetConfiguration)
|
|
142
|
+
{
|
|
143
|
+
pRecord.RecordSetConfiguration = tmpRecordSetConfiguration;
|
|
144
|
+
}
|
|
145
|
+
if (!pRecord.ViewContext)
|
|
146
|
+
{
|
|
147
|
+
pRecord.ViewContext = tmpViewContext;
|
|
148
|
+
}
|
|
149
|
+
let tmpRenderGUID = this.pict.getUUID();
|
|
150
|
+
|
|
151
|
+
/** @type {import('pict-view')} */
|
|
152
|
+
const tmpView = this.pict.views[tmpViewHash];
|
|
153
|
+
|
|
154
|
+
return tmpView.renderAsync('__Virtual', `__TemplateOutputCache.${tmpRenderGUID}`, pRecord,
|
|
155
|
+
(pError, pResult) =>
|
|
156
|
+
{
|
|
157
|
+
if (pError)
|
|
158
|
+
{
|
|
159
|
+
this.log.warn(`Pict: Filter View Template Render: Error rendering view [${tmpViewHash}]`, pError);
|
|
160
|
+
return fCallback(pError, '');
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
let tmpResult = this.pict.__TemplateOutputCache[tmpRenderGUID];
|
|
164
|
+
// TODO: Uncomment this when we like how it's working
|
|
165
|
+
//delete this.pict.__TemplateOutputCache[tmpRenderGUID];
|
|
166
|
+
|
|
167
|
+
return fCallback(null, tmpResult);
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
module.exports = PictTemplateFilterViewInstruction;
|