pict-section-recordset 1.0.43 → 1.0.45
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 +199 -3
- package/example_applications/simple_entity/html/index.html +6 -0
- package/package.json +2 -2
- package/source/providers/Filter-Data-Provider.js +371 -0
- package/source/providers/RecordSet-Link-Manager.js +9 -1
- package/source/providers/RecordSet-RecordProvider-Base.js +1 -1
- package/source/providers/RecordSet-RecordProvider-MeadowEndpoints.js +76 -43
- package/source/services/RecordsSet-MetaController.js +48 -1
- package/source/templates/Pict-Template-FilterInstanceViews.js +11 -7
- package/source/views/RecordSet-Filters.js +78 -45
- package/source/views/filters/RecordSet-Filter-Base.js +19 -1
- package/source/views/filters/RecordSet-Filter-ExternalJoinSelectedValue.js +270 -0
- package/source/views/filters/RecordSet-Filter-ExternalJoinSelectedValueList.js +277 -0
- package/source/views/filters/RecordSet-Filter-InternalJoinSelectedValue.js +270 -0
- package/source/views/filters/RecordSet-Filter-InternalJoinSelectedValueList.js +277 -0
- package/source/views/filters/index.js +4 -0
- package/types/providers/Filter-Data-Provider.d.ts +120 -0
- package/types/providers/Filter-Data-Provider.d.ts.map +1 -0
- package/types/providers/RecordSet-Link-Manager.d.ts +10 -5
- package/types/providers/RecordSet-Link-Manager.d.ts.map +1 -1
- package/types/providers/RecordSet-RecordProvider-MeadowEndpoints.d.ts +1 -1
- package/types/providers/RecordSet-RecordProvider-MeadowEndpoints.d.ts.map +1 -1
- package/types/services/RecordsSet-MetaController.d.ts +36 -7
- package/types/services/RecordsSet-MetaController.d.ts.map +1 -1
- package/types/templates/Pict-Template-FilterInstanceViews.d.ts +1 -1
- package/types/templates/Pict-Template-FilterInstanceViews.d.ts.map +1 -1
- package/types/views/RecordSet-Filters.d.ts +10 -0
- package/types/views/RecordSet-Filters.d.ts.map +1 -1
- package/types/views/filters/RecordSet-Filter-Base.d.ts +10 -0
- package/types/views/filters/RecordSet-Filter-Base.d.ts.map +1 -1
- package/types/views/filters/RecordSet-Filter-ExternalJoinSelectedValue.d.ts +24 -0
- package/types/views/filters/RecordSet-Filter-ExternalJoinSelectedValue.d.ts.map +1 -0
- package/types/views/filters/RecordSet-Filter-ExternalJoinSelectedValueList.d.ts +24 -0
- package/types/views/filters/RecordSet-Filter-ExternalJoinSelectedValueList.d.ts.map +1 -0
- package/types/views/filters/RecordSet-Filter-InternalJoinSelectedValue.d.ts +24 -0
- package/types/views/filters/RecordSet-Filter-InternalJoinSelectedValue.d.ts.map +1 -0
- package/types/views/filters/RecordSet-Filter-InternalJoinSelectedValueList.d.ts +24 -0
- package/types/views/filters/RecordSet-Filter-InternalJoinSelectedValueList.d.ts.map +1 -0
- package/types/views/filters/index.d.ts +4 -0
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
|
|
2
|
+
const ViewRecordSetSUBSETFilterBase = require('./RecordSet-Filter-Base');
|
|
3
|
+
|
|
4
|
+
const _DEFAULT_CONFIGURATION_Filter_ExternalJoin_SelectedValue =
|
|
5
|
+
{
|
|
6
|
+
ViewIdentifier: 'PRSP-FilterType-ExternalJoinSelectedValue',
|
|
7
|
+
|
|
8
|
+
Templates:
|
|
9
|
+
[
|
|
10
|
+
{
|
|
11
|
+
Hash: 'PRSP-Filter-ExternalJoin-SelectedValue-Template',
|
|
12
|
+
Template: /*html*/`
|
|
13
|
+
<!-- DefaultPackage pict view template: [PRSP-Filter-ExternalJoin-SelectedValue-Template] -->
|
|
14
|
+
<table>
|
|
15
|
+
<tbody>
|
|
16
|
+
<td valign="top">{~T:PRSP-Filter-ExternalJoin-SelectedValue-SearchResults~}</td><td valign="top">{~T:PRSP-Filter-ExternalJoin-SelectedValue-SelectedValues~}</td>
|
|
17
|
+
</tbody>
|
|
18
|
+
</table>
|
|
19
|
+
<!-- DefaultPackage end view template: [PRSP-Filter-ExternalJoin-SelectedValue-Template] -->
|
|
20
|
+
`
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
Hash: 'PRSP-Filter-ExternalJoin-SelectedValue-SearchResults',
|
|
24
|
+
Template: /*html*/`
|
|
25
|
+
<!-- DefaultPackage pict view template: [PRSP-Filter-ExternalJoin-SearchResults] -->
|
|
26
|
+
<form id="PRSP_Filter_{~D:Record.Hash~}_Search_Form" onsubmit="_Pict.views['{~D:Context[0].Hash~}'].performSearch(event, '{~D:Record.ClauseAddress~}', '{~D:Record.Hash~}'); return false;">
|
|
27
|
+
<input id="PRSP_Filter_{~D:Record.Hash~}_Search_Value" type="text" placeholder="Search..." value="{~D:Record.SearchInputValue~}" />
|
|
28
|
+
<button type="submit" id="PRSP_Filter_{~D:Record.Hash~}_Button_Search" onclick="_Pict.views['{~D:Context[0].Hash~}'].performSearch(event, '{~D:Record.ClauseAddress~}', '{~D:Record.Hash~}')">Search</button>
|
|
29
|
+
</form>
|
|
30
|
+
<table>
|
|
31
|
+
<thead>
|
|
32
|
+
<tr><th colspan="2">{~D:Record.Label~}</th></tr>
|
|
33
|
+
</thead>
|
|
34
|
+
<tbody>
|
|
35
|
+
{~TSWP:PRSP-Filter-ExternalJoin-SelectedValue-SearchResults-Entry:Record.SearchResults:Record~}
|
|
36
|
+
</tbody>
|
|
37
|
+
</table>
|
|
38
|
+
<button type="button" id="PRSP_Filter_{~D:Record.Hash~}_Button_LoadMore" class="is-hidden" onclick="_Pict.views['{~D:Context[0].Hash~}'].loadMore(event, '{~D:Record.ClauseAddress~}', '{~D:Record.Hash~}', {~D:Record.SearchResultsOffset:0~})">Load More</button>
|
|
39
|
+
<!-- DefaultPackage end view template: [PRSP-Filter-ExternalJoin-SearchResults] -->
|
|
40
|
+
`
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
Hash: 'PRSP-Filter-ExternalJoin-SelectedValue-SelectedValues',
|
|
44
|
+
Template: /*html*/`
|
|
45
|
+
<!-- DefaultPackage view template: [PRSP-Filter-ExternalJoin-SelectedValue-SelectedValues] -->
|
|
46
|
+
<table>
|
|
47
|
+
<thead>
|
|
48
|
+
<tr><th colspan="2">Selection</th></tr>
|
|
49
|
+
</thead>
|
|
50
|
+
<tbody>
|
|
51
|
+
{~TSWP:PRSP-Filter-ExternalJoin-SelectedValue-SelectedValues-Entry:Record.SelectedValues:Record~}
|
|
52
|
+
</tbody>
|
|
53
|
+
</table>
|
|
54
|
+
<!-- DefaultPackage end view template: [PRSP-Filter-ExternalJoin-SelectedValue-SelectedValues] -->
|
|
55
|
+
`
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
Hash: 'PRSP-Filter-ExternalJoin-SelectedValue-SearchResults-Entry',
|
|
59
|
+
Template: /*html*/`
|
|
60
|
+
<!-- DefaultPackage pict view template: [PRSP-Filter-ExternalJoin-SelectedValue-Template] -->
|
|
61
|
+
<tr><td><button onclick="_Pict.views['{~D:Context[0].Hash~}'].handleSelect(event, {~DVBK:Record.Data:Record.Payload.ExternalFilterTableLookupColumn~}, '{~D:Record.Payload.ClauseAddress~}', '{~D:Record.Payload.Hash~}')">Select</button></td><td>{~TFA:Record.Payload.ExternalRecordDisplayTemplate:Record~}</td></tr>
|
|
62
|
+
<!-- DefaultPackage end view template: [PRSP-Filter-ExternalJoin-SelectedValue-Template] -->
|
|
63
|
+
`
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
Hash: 'PRSP-Filter-ExternalJoin-SelectedValue-SelectedValues-Entry',
|
|
67
|
+
Template: /*html*/`
|
|
68
|
+
<!-- DefaultPackage pict view template: [PRSP-Filter-ExternalJoin-SelectedValue-SelectedValues-Entry] -->
|
|
69
|
+
<tr><td><button onclick="_Pict.views['{~D:Context[0].Hash~}'].handleRemove(event, {~DVBK:Record.Data:Record.Payload.ExternalFilterTableLookupColumn~}, '{~D:Record.Payload.ClauseAddress~}', '{~D:Record.Payload.Hash~}')">Remove</button></td><td>{~TFA:Record.Payload.ExternalRecordDisplayTemplate:Record~}</td></tr>
|
|
70
|
+
<!-- DefaultPackage end view template: [PRSP-Filter-ExternalJoin-SelectedValue-SelectedValues-Entry] -->
|
|
71
|
+
`
|
|
72
|
+
}
|
|
73
|
+
],
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
class ViewRecordSetSUBSETFilterExternalJoinSelectedValue extends ViewRecordSetSUBSETFilterBase
|
|
77
|
+
{
|
|
78
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
79
|
+
{
|
|
80
|
+
if (!pOptions.PageSize)
|
|
81
|
+
{
|
|
82
|
+
pOptions.PageSize = 15; // default page size for search results
|
|
83
|
+
}
|
|
84
|
+
super(pFable, pOptions, pServiceHash);
|
|
85
|
+
/*
|
|
86
|
+
* show / hide the complex editor since it'll be large ?
|
|
87
|
+
* selected record lookup values
|
|
88
|
+
* using bundle to load those records (if any)
|
|
89
|
+
* templating out the selection
|
|
90
|
+
* templating out the search results
|
|
91
|
+
* controls to add search result values to selection
|
|
92
|
+
*/
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @param {Record<string, any>} pRecord
|
|
97
|
+
*/
|
|
98
|
+
prepareRecord(pRecord)
|
|
99
|
+
{
|
|
100
|
+
super.prepareRecord(pRecord);
|
|
101
|
+
|
|
102
|
+
pRecord.ClauseDescriptor.DataType = 'Number';
|
|
103
|
+
if (!pRecord.ExternalFilterTableLookupColumn)
|
|
104
|
+
{
|
|
105
|
+
pRecord.ExternalFilterTableLookupColumn = `ID${pRecord.ExternalFilterByTable}`;
|
|
106
|
+
}
|
|
107
|
+
if (!pRecord.SearchResults)
|
|
108
|
+
{
|
|
109
|
+
pRecord.SearchResults = [];
|
|
110
|
+
}
|
|
111
|
+
if (!pRecord.SelectedValues)
|
|
112
|
+
{
|
|
113
|
+
pRecord.SelectedValues = [];
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
getFilterFormTemplate()
|
|
118
|
+
{
|
|
119
|
+
return 'PRSP-Filter-ExternalJoin-SelectedValue-Template';
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @param {UIEvent} pEvent
|
|
124
|
+
* @param {string} pClauseInformaryAddress
|
|
125
|
+
* @param {string} pClauseHash
|
|
126
|
+
*/
|
|
127
|
+
loadMore(pEvent, pClauseInformaryAddress, pClauseHash, pCurrentOffset = 0)
|
|
128
|
+
{
|
|
129
|
+
this.performSearch(pEvent, pClauseInformaryAddress, pClauseHash, pCurrentOffset + this.options.PageSize);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* @param {UIEvent} pEvent
|
|
134
|
+
* @param {string} pClauseInformaryAddress
|
|
135
|
+
* @param {string} pClauseHash
|
|
136
|
+
* @param {number} [pOffset=0] - The offset for the search results, defaults to 0
|
|
137
|
+
*/
|
|
138
|
+
performSearch(pEvent, pClauseInformaryAddress, pClauseHash, pOffset = 0)
|
|
139
|
+
{
|
|
140
|
+
pEvent.preventDefault();
|
|
141
|
+
const tmpClause = this.getInformaryScopedValue(pClauseInformaryAddress);
|
|
142
|
+
if (!tmpClause)
|
|
143
|
+
{
|
|
144
|
+
this.pict.log.error(`[Filter-ExternalJoinSelectedValue] No clause found for address: ${pClauseInformaryAddress}`);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
tmpClause.SearchResultsOffset = pOffset;
|
|
148
|
+
// get the input value (search box)
|
|
149
|
+
const tmpSearchInputValue = pOffset > 0 ? tmpClause.SearchInputValue : this.pict.ContentAssignment.readContent(`#PRSP_Filter_${tmpClause.Hash}_Search_Value`);
|
|
150
|
+
tmpClause.SearchInputValue = tmpSearchInputValue;
|
|
151
|
+
if (!tmpSearchInputValue)
|
|
152
|
+
{
|
|
153
|
+
tmpClause.SearchResults = [];
|
|
154
|
+
tmpClause.LoadMoreEnabled = false;
|
|
155
|
+
const tmpRecord = Object.assign({ ClauseAddress: pClauseInformaryAddress }, tmpClause);
|
|
156
|
+
this.prepareRecord(tmpRecord);
|
|
157
|
+
const tmpDestinationAddress = `#PRSP_Filter_Container_${pClauseHash}`;
|
|
158
|
+
this.render(null, tmpDestinationAddress, tmpRecord);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const tmpFilterByColumns = tmpClause.ExternalFilterByColumns || (tmpClause.ExternalFilterByColumn ? [ tmpClause.ExternalFilterByColumn ] : [ 'Name' ]);
|
|
162
|
+
const tmpMeadowFilter = tmpFilterByColumns.map((pColumn) => `FBVOR~${pColumn}~LK~${encodeURIComponent(`%${tmpSearchInputValue}%`)}`).join('~');
|
|
163
|
+
// bundle load the remote records and put them in the clause
|
|
164
|
+
this.pict.EntityProvider.gatherDataFromServer(
|
|
165
|
+
[
|
|
166
|
+
{
|
|
167
|
+
Entity: tmpClause.ExternalFilterByTable,
|
|
168
|
+
Filter: tmpMeadowFilter,
|
|
169
|
+
Destination: pOffset > 0 ? `${this.getInformaryAddressPrefix()}${pClauseInformaryAddress}.SearchResultsAppend` : `${this.getInformaryAddressPrefix()}${pClauseInformaryAddress}.SearchResults`,
|
|
170
|
+
RecordStartCursor: pOffset,
|
|
171
|
+
PageSize: this.options.PageSize,
|
|
172
|
+
}
|
|
173
|
+
],
|
|
174
|
+
(pError, pResult) =>
|
|
175
|
+
{
|
|
176
|
+
if (pOffset > 0 && tmpClause.SearchResultsAppend?.length > 0)
|
|
177
|
+
{
|
|
178
|
+
tmpClause.SearchResults = tmpClause.SearchResults.concat(tmpClause.SearchResultsAppend);
|
|
179
|
+
}
|
|
180
|
+
delete tmpClause.SearchResultsAppend;
|
|
181
|
+
tmpClause.SearchResultsOffset = pOffset;
|
|
182
|
+
const tmpRecord = Object.assign({ ClauseAddress: pClauseInformaryAddress }, tmpClause);
|
|
183
|
+
this.prepareRecord(tmpRecord);
|
|
184
|
+
const tmpDestinationAddress = `#PRSP_Filter_Container_${pClauseHash}`;
|
|
185
|
+
this.render(null, tmpDestinationAddress, tmpRecord);
|
|
186
|
+
const tmpLoadedRecords = pOffset > 0 ? tmpClause.SearchResultsAppend : tmpClause.SearchResults;
|
|
187
|
+
const tmpLoadMoreEnabled = tmpLoadedRecords && tmpLoadedRecords.length >= this.options.PageSize;
|
|
188
|
+
tmpClause.LoadMoreEnabled = tmpLoadMoreEnabled;
|
|
189
|
+
if (tmpClause.LoadMoreEnabled)
|
|
190
|
+
{
|
|
191
|
+
this.pict.ContentAssignment.removeClass(`#PRSP_Filter_${tmpClause.Hash}_Button_LoadMore`, 'is-hidden');
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
handleSelect(pEvent, pRecordLookupValue, pClauseInformaryAddress, pClauseHash)
|
|
197
|
+
{
|
|
198
|
+
pEvent.preventDefault();
|
|
199
|
+
const tmpClause = this.getInformaryScopedValue(pClauseInformaryAddress);
|
|
200
|
+
if (!tmpClause)
|
|
201
|
+
{
|
|
202
|
+
this.pict.log.error(`[Filter-ExternalJoinSelectedValue] No clause found for address: ${pClauseInformaryAddress}`);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
const tmpRecordLookupColumn = tmpClause.ExternalFilterTableLookupColumn || `ID${tmpClause.ExternalFilterByTable}`;
|
|
206
|
+
const tmpRecordToSelect = tmpClause.SearchResults.find((r) => r[tmpRecordLookupColumn] == pRecordLookupValue);
|
|
207
|
+
if (!tmpRecordToSelect)
|
|
208
|
+
{
|
|
209
|
+
this.pict.log.error(`[Filter-ExternalJoinSelectedValue] No record found to add for value: ${pRecordLookupValue}`);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
if (!tmpClause.SelectedValues)
|
|
213
|
+
{
|
|
214
|
+
tmpClause.SelectedValues = [];
|
|
215
|
+
}
|
|
216
|
+
if (tmpClause.SelectedValues.some((pSV) => pSV[tmpRecordLookupColumn] == pRecordLookupValue))
|
|
217
|
+
{
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
const tmpValue = tmpRecordToSelect[tmpRecordLookupColumn];
|
|
221
|
+
if (tmpValue == null)
|
|
222
|
+
{
|
|
223
|
+
this.pict.log.error(`[Filter-ExternalJoinSelectedValue] No value found in record to add: ${JSON.stringify(tmpRecordToSelect)}`);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
tmpClause.SelectedValues = [ tmpRecordToSelect ];
|
|
227
|
+
tmpClause.Values = [ tmpValue ];
|
|
228
|
+
const tmpRecord = Object.assign({ ClauseAddress: pClauseInformaryAddress }, tmpClause);
|
|
229
|
+
this.prepareRecord(tmpRecord);
|
|
230
|
+
const tmpDestinationAddress = `#PRSP_Filter_Container_${pClauseHash}`;
|
|
231
|
+
this.render(null, tmpDestinationAddress, tmpRecord);
|
|
232
|
+
if (tmpClause.LoadMoreEnabled)
|
|
233
|
+
{
|
|
234
|
+
this.pict.ContentAssignment.removeClass(`#PRSP_Filter_${tmpClause.Hash}_Button_LoadMore`, 'is-hidden');
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
handleRemove(pEvent, pRecordLookupValue, pClauseInformaryAddress, pClauseHash)
|
|
239
|
+
{
|
|
240
|
+
pEvent.preventDefault();
|
|
241
|
+
const tmpClause = this.getInformaryScopedValue(pClauseInformaryAddress);
|
|
242
|
+
if (!tmpClause)
|
|
243
|
+
{
|
|
244
|
+
this.pict.log.error(`[Filter-ExternalJoinSelectedValue] No clause found for address: ${pClauseInformaryAddress}`);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const tmpRecordLookupColumn = tmpClause.ExternalFilterTableLookupColumn || `ID${tmpClause.ExternalFilterByTable}`;
|
|
248
|
+
const tmpRecordIndexToRemove = tmpClause.SelectedValues.findIndex((r) => r[tmpRecordLookupColumn] == pRecordLookupValue);
|
|
249
|
+
if (tmpRecordIndexToRemove < 0)
|
|
250
|
+
{
|
|
251
|
+
this.pict.log.error(`[Filter-ExternalJoinSelectedValue] No record found to remove for value: ${pRecordLookupValue}`);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
const tmpRecordToRemove = tmpClause.SelectedValues.splice(tmpRecordIndexToRemove, 1)[0];
|
|
255
|
+
const tmpValue = tmpRecordToRemove[tmpRecordLookupColumn];
|
|
256
|
+
tmpClause.Values = tmpClause.Values.filter((pV) => pV !== tmpValue);
|
|
257
|
+
const tmpRecord = Object.assign({ ClauseAddress: pClauseInformaryAddress }, tmpClause);
|
|
258
|
+
this.prepareRecord(tmpRecord);
|
|
259
|
+
const tmpDestinationAddress = `#PRSP_Filter_Container_${pClauseHash}`;
|
|
260
|
+
this.render(null, tmpDestinationAddress, tmpRecord);
|
|
261
|
+
if (tmpClause.LoadMoreEnabled)
|
|
262
|
+
{
|
|
263
|
+
this.pict.ContentAssignment.removeClass(`#PRSP_Filter_${tmpClause.Hash}_Button_LoadMore`, 'is-hidden');
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
module.exports = ViewRecordSetSUBSETFilterExternalJoinSelectedValue;
|
|
269
|
+
|
|
270
|
+
module.exports.default_configuration = Object.assign({}, ViewRecordSetSUBSETFilterExternalJoinSelectedValue.default_configuration, _DEFAULT_CONFIGURATION_Filter_ExternalJoin_SelectedValue);
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
|
|
2
|
+
const ViewRecordSetSUBSETFilterBase = require('./RecordSet-Filter-Base');
|
|
3
|
+
|
|
4
|
+
const _DEFAULT_CONFIGURATION_Filter_ExternalJoin_SelectedValueList =
|
|
5
|
+
{
|
|
6
|
+
ViewIdentifier: 'PRSP-FilterType-ExternalJoinSelectedValueList',
|
|
7
|
+
|
|
8
|
+
Templates:
|
|
9
|
+
[
|
|
10
|
+
{
|
|
11
|
+
Hash: 'PRSP-Filter-ExternalJoin-SelectedValueList-Template',
|
|
12
|
+
Template: /*html*/`
|
|
13
|
+
<!-- DefaultPackage pict view template: [PRSP-Filter-ExternalJoin-SelectedValueList-Template] -->
|
|
14
|
+
<table>
|
|
15
|
+
<tbody>
|
|
16
|
+
<td valign="top">{~T:PRSP-Filter-ExternalJoin-SelectedValueList-SearchResults~}</td><td valign="top">{~T:PRSP-Filter-ExternalJoin-SelectedValueList-SelectedValues~}</td>
|
|
17
|
+
</tbody>
|
|
18
|
+
</table>
|
|
19
|
+
<!-- DefaultPackage end view template: [PRSP-Filter-ExternalJoin-SelectedValueList-Template] -->
|
|
20
|
+
`
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
Hash: 'PRSP-Filter-ExternalJoin-SelectedValueList-SearchResults',
|
|
24
|
+
Template: /*html*/`
|
|
25
|
+
<!-- DefaultPackage pict view template: [PRSP-Filter-ExternalJoin-SearchResults] -->
|
|
26
|
+
<form id="PRSP_Filter_{~D:Record.Hash~}_Search_Form" onsubmit="_Pict.views['{~D:Context[0].Hash~}'].performSearch(event, '{~D:Record.ClauseAddress~}', '{~D:Record.Hash~}'); return false;">
|
|
27
|
+
<input id="PRSP_Filter_{~D:Record.Hash~}_Search_Value" type="text" placeholder="Search..." value="{~D:Record.SearchInputValue~}" />
|
|
28
|
+
<button type="submit" id="PRSP_Filter_{~D:Record.Hash~}_Button_Search" onclick="_Pict.views['{~D:Context[0].Hash~}'].performSearch(event, '{~D:Record.ClauseAddress~}', '{~D:Record.Hash~}')">Search</button>
|
|
29
|
+
</form>
|
|
30
|
+
<table>
|
|
31
|
+
<thead>
|
|
32
|
+
<tr><th colspan="2">{~D:Record.Label~}</th></tr>
|
|
33
|
+
</thead>
|
|
34
|
+
<tbody>
|
|
35
|
+
{~TSWP:PRSP-Filter-ExternalJoin-SelectedValueList-SearchResults-Entry:Record.SearchResults:Record~}
|
|
36
|
+
</tbody>
|
|
37
|
+
</table>
|
|
38
|
+
<button type="button" id="PRSP_Filter_{~D:Record.Hash~}_Button_LoadMore" class="is-hidden" onclick="_Pict.views['{~D:Context[0].Hash~}'].loadMore(event, '{~D:Record.ClauseAddress~}', '{~D:Record.Hash~}', {~D:Record.SearchResultsOffset:0~})">Load More</button>
|
|
39
|
+
<!-- DefaultPackage end view template: [PRSP-Filter-ExternalJoin-SearchResults] -->
|
|
40
|
+
`
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
Hash: 'PRSP-Filter-ExternalJoin-SelectedValueList-SelectedValues',
|
|
44
|
+
Template: /*html*/`
|
|
45
|
+
<!-- DefaultPackage view template: [PRSP-Filter-ExternalJoin-SelectedValueList-SelectedValues] -->
|
|
46
|
+
<table>
|
|
47
|
+
<thead>
|
|
48
|
+
<tr><th colspan="2">Selection</th></tr>
|
|
49
|
+
</thead>
|
|
50
|
+
<tbody>
|
|
51
|
+
{~TSWP:PRSP-Filter-ExternalJoin-SelectedValueList-SelectedValues-Entry:Record.SelectedValues:Record~}
|
|
52
|
+
</tbody>
|
|
53
|
+
</table>
|
|
54
|
+
<!-- DefaultPackage end view template: [PRSP-Filter-ExternalJoin-SelectedValueList-SelectedValues] -->
|
|
55
|
+
`
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
Hash: 'PRSP-Filter-ExternalJoin-SelectedValueList-SearchResults-Entry',
|
|
59
|
+
Template: /*html*/`
|
|
60
|
+
<!-- DefaultPackage pict view template: [PRSP-Filter-ExternalJoin-SelectedValueList-Template] -->
|
|
61
|
+
<tr><td><button onclick="_Pict.views['{~D:Context[0].Hash~}'].handleAdd(event, {~DVBK:Record.Data:Record.Payload.ExternalFilterTableLookupColumn~}, '{~D:Record.Payload.ClauseAddress~}', '{~D:Record.Payload.Hash~}')">Add</button></td><td>{~TFA:Record.Payload.ExternalRecordDisplayTemplate:Record~}</td></tr>
|
|
62
|
+
<!-- DefaultPackage end view template: [PRSP-Filter-ExternalJoin-SelectedValueList-Template] -->
|
|
63
|
+
`
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
Hash: 'PRSP-Filter-ExternalJoin-SelectedValueList-SelectedValues-Entry',
|
|
67
|
+
Template: /*html*/`
|
|
68
|
+
<!-- DefaultPackage pict view template: [PRSP-Filter-ExternalJoin-SelectedValueList-SelectedValues-Entry] -->
|
|
69
|
+
<tr><td><button onclick="_Pict.views['{~D:Context[0].Hash~}'].handleRemove(event, {~DVBK:Record.Data:Record.Payload.ExternalFilterTableLookupColumn~}, '{~D:Record.Payload.ClauseAddress~}', '{~D:Record.Payload.Hash~}')">Remove</button></td><td>{~TFA:Record.Payload.ExternalRecordDisplayTemplate:Record~}</td></tr>
|
|
70
|
+
<!-- DefaultPackage end view template: [PRSP-Filter-ExternalJoin-SelectedValueList-SelectedValues-Entry] -->
|
|
71
|
+
`
|
|
72
|
+
}
|
|
73
|
+
],
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
class ViewRecordSetSUBSETFilterExternalJoinSelectedValueList extends ViewRecordSetSUBSETFilterBase
|
|
77
|
+
{
|
|
78
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
79
|
+
{
|
|
80
|
+
if (!pOptions.PageSize)
|
|
81
|
+
{
|
|
82
|
+
pOptions.PageSize = 15; // default page size for search results
|
|
83
|
+
}
|
|
84
|
+
super(pFable, pOptions, pServiceHash);
|
|
85
|
+
/*
|
|
86
|
+
* show / hide the complex editor since it'll be large ?
|
|
87
|
+
* selected record lookup values
|
|
88
|
+
* using bundle to load those records (if any)
|
|
89
|
+
* templating out the selection
|
|
90
|
+
* templating out the search results
|
|
91
|
+
* controls to add search result values to selection
|
|
92
|
+
*/
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @param {Record<string, any>} pRecord
|
|
97
|
+
*/
|
|
98
|
+
prepareRecord(pRecord)
|
|
99
|
+
{
|
|
100
|
+
super.prepareRecord(pRecord);
|
|
101
|
+
|
|
102
|
+
pRecord.ClauseDescriptor.DataType = 'Number';
|
|
103
|
+
if (!pRecord.ExternalFilterTableLookupColumn)
|
|
104
|
+
{
|
|
105
|
+
pRecord.ExternalFilterTableLookupColumn = `ID${pRecord.ExternalFilterByTable}`;
|
|
106
|
+
}
|
|
107
|
+
if (!pRecord.SearchResults)
|
|
108
|
+
{
|
|
109
|
+
pRecord.SearchResults = [];
|
|
110
|
+
}
|
|
111
|
+
if (!pRecord.SelectedValues)
|
|
112
|
+
{
|
|
113
|
+
pRecord.SelectedValues = [];
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
getFilterFormTemplate()
|
|
118
|
+
{
|
|
119
|
+
return 'PRSP-Filter-ExternalJoin-SelectedValueList-Template';
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @param {UIEvent} pEvent
|
|
124
|
+
* @param {string} pClauseInformaryAddress
|
|
125
|
+
* @param {string} pClauseHash
|
|
126
|
+
*/
|
|
127
|
+
loadMore(pEvent, pClauseInformaryAddress, pClauseHash, pCurrentOffset = 0)
|
|
128
|
+
{
|
|
129
|
+
this.performSearch(pEvent, pClauseInformaryAddress, pClauseHash, pCurrentOffset + this.options.PageSize);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* @param {UIEvent} pEvent
|
|
134
|
+
* @param {string} pClauseInformaryAddress
|
|
135
|
+
* @param {string} pClauseHash
|
|
136
|
+
* @param {number} [pOffset=0] - The offset for the search results, defaults to 0
|
|
137
|
+
*/
|
|
138
|
+
performSearch(pEvent, pClauseInformaryAddress, pClauseHash, pOffset = 0)
|
|
139
|
+
{
|
|
140
|
+
pEvent.preventDefault();
|
|
141
|
+
const tmpClause = this.getInformaryScopedValue(pClauseInformaryAddress);
|
|
142
|
+
if (!tmpClause)
|
|
143
|
+
{
|
|
144
|
+
this.pict.log.error(`[Filter-ExternalJoinSelectedValueList] No clause found for address: ${pClauseInformaryAddress}`);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
tmpClause.SearchResultsOffset = pOffset;
|
|
148
|
+
// get the input value (search box)
|
|
149
|
+
const tmpSearchInputValue = pOffset > 0 ? tmpClause.SearchInputValue : this.pict.ContentAssignment.readContent(`#PRSP_Filter_${tmpClause.Hash}_Search_Value`);
|
|
150
|
+
tmpClause.SearchInputValue = tmpSearchInputValue;
|
|
151
|
+
if (!tmpSearchInputValue)
|
|
152
|
+
{
|
|
153
|
+
tmpClause.SearchResults = [];
|
|
154
|
+
tmpClause.LoadMoreEnabled = false;
|
|
155
|
+
const tmpRecord = Object.assign({ ClauseAddress: pClauseInformaryAddress }, tmpClause);
|
|
156
|
+
this.prepareRecord(tmpRecord);
|
|
157
|
+
const tmpDestinationAddress = `#PRSP_Filter_Container_${pClauseHash}`;
|
|
158
|
+
this.render(null, tmpDestinationAddress, tmpRecord);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const tmpFilterByColumns = tmpClause.ExternalFilterByColumns || (tmpClause.ExternalFilterByColumn ? [ tmpClause.ExternalFilterByColumn ] : [ 'Name' ]);
|
|
162
|
+
const tmpMeadowFilter = tmpFilterByColumns.map((pColumn) => `FBVOR~${pColumn}~LK~${encodeURIComponent(`%${tmpSearchInputValue}%`)}`).join('~');
|
|
163
|
+
// bundle load the remote records and put them in the clause
|
|
164
|
+
this.pict.EntityProvider.gatherDataFromServer(
|
|
165
|
+
[
|
|
166
|
+
{
|
|
167
|
+
Entity: tmpClause.ExternalFilterByTable,
|
|
168
|
+
Filter: tmpMeadowFilter,
|
|
169
|
+
Destination: pOffset > 0 ? `${this.getInformaryAddressPrefix()}${pClauseInformaryAddress}.SearchResultsAppend` : `${this.getInformaryAddressPrefix()}${pClauseInformaryAddress}.SearchResults`,
|
|
170
|
+
RecordStartCursor: pOffset,
|
|
171
|
+
PageSize: this.options.PageSize,
|
|
172
|
+
}
|
|
173
|
+
],
|
|
174
|
+
(pError, pResult) =>
|
|
175
|
+
{
|
|
176
|
+
if (pOffset > 0 && tmpClause.SearchResultsAppend?.length > 0)
|
|
177
|
+
{
|
|
178
|
+
tmpClause.SearchResults = tmpClause.SearchResults.concat(tmpClause.SearchResultsAppend);
|
|
179
|
+
}
|
|
180
|
+
delete tmpClause.SearchResultsAppend;
|
|
181
|
+
tmpClause.SearchResultsOffset = pOffset;
|
|
182
|
+
const tmpRecord = Object.assign({ ClauseAddress: pClauseInformaryAddress }, tmpClause);
|
|
183
|
+
this.prepareRecord(tmpRecord);
|
|
184
|
+
const tmpDestinationAddress = `#PRSP_Filter_Container_${pClauseHash}`;
|
|
185
|
+
this.render(null, tmpDestinationAddress, tmpRecord);
|
|
186
|
+
const tmpLoadedRecords = pOffset > 0 ? tmpClause.SearchResultsAppend : tmpClause.SearchResults;
|
|
187
|
+
const tmpLoadMoreEnabled = tmpLoadedRecords && tmpLoadedRecords.length >= this.options.PageSize;
|
|
188
|
+
tmpClause.LoadMoreEnabled = tmpLoadMoreEnabled;
|
|
189
|
+
if (tmpClause.LoadMoreEnabled)
|
|
190
|
+
{
|
|
191
|
+
this.pict.ContentAssignment.removeClass(`#PRSP_Filter_${tmpClause.Hash}_Button_LoadMore`, 'is-hidden');
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
handleAdd(pEvent, pRecordLookupValue, pClauseInformaryAddress, pClauseHash)
|
|
197
|
+
{
|
|
198
|
+
pEvent.preventDefault();
|
|
199
|
+
const tmpClause = this.getInformaryScopedValue(pClauseInformaryAddress);
|
|
200
|
+
if (!tmpClause)
|
|
201
|
+
{
|
|
202
|
+
this.pict.log.error(`[Filter-ExternalJoinSelectedValueList] No clause found for address: ${pClauseInformaryAddress}`);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
const tmpRecordLookupColumn = tmpClause.ExternalFilterTableLookupColumn || `ID${tmpClause.ExternalFilterByTable}`;
|
|
206
|
+
const tmpRecordToAdd = tmpClause.SearchResults.find((r) => r[tmpRecordLookupColumn] == pRecordLookupValue);
|
|
207
|
+
if (!tmpRecordToAdd)
|
|
208
|
+
{
|
|
209
|
+
this.pict.log.error(`[Filter-ExternalJoinSelectedValueList] No record found to add for value: ${pRecordLookupValue}`);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
if (!tmpClause.SelectedValues)
|
|
213
|
+
{
|
|
214
|
+
tmpClause.SelectedValues = [];
|
|
215
|
+
}
|
|
216
|
+
if (tmpClause.SelectedValues.some((pSV) => pSV[tmpRecordLookupColumn] == pRecordLookupValue))
|
|
217
|
+
{
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
const tmpValue = tmpRecordToAdd[tmpRecordLookupColumn];
|
|
221
|
+
if (tmpValue == null)
|
|
222
|
+
{
|
|
223
|
+
this.pict.log.error(`[Filter-ExternalJoinSelectedValueList] No value found in record to add: ${JSON.stringify(tmpRecordToAdd)}`);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
tmpClause.SelectedValues.push(tmpRecordToAdd);
|
|
227
|
+
if (!tmpClause.Values)
|
|
228
|
+
{
|
|
229
|
+
tmpClause.Values = [];
|
|
230
|
+
}
|
|
231
|
+
if (!tmpClause.Values.some((pV) => pV == tmpValue))
|
|
232
|
+
{
|
|
233
|
+
tmpClause.Values.push(tmpValue);
|
|
234
|
+
}
|
|
235
|
+
const tmpRecord = Object.assign({ ClauseAddress: pClauseInformaryAddress }, tmpClause);
|
|
236
|
+
this.prepareRecord(tmpRecord);
|
|
237
|
+
const tmpDestinationAddress = `#PRSP_Filter_Container_${pClauseHash}`;
|
|
238
|
+
this.render(null, tmpDestinationAddress, tmpRecord);
|
|
239
|
+
if (tmpClause.LoadMoreEnabled)
|
|
240
|
+
{
|
|
241
|
+
this.pict.ContentAssignment.removeClass(`#PRSP_Filter_${tmpClause.Hash}_Button_LoadMore`, 'is-hidden');
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
handleRemove(pEvent, pRecordLookupValue, pClauseInformaryAddress, pClauseHash)
|
|
246
|
+
{
|
|
247
|
+
pEvent.preventDefault();
|
|
248
|
+
const tmpClause = this.getInformaryScopedValue(pClauseInformaryAddress);
|
|
249
|
+
if (!tmpClause)
|
|
250
|
+
{
|
|
251
|
+
this.pict.log.error(`[Filter-ExternalJoinSelectedValueList] No clause found for address: ${pClauseInformaryAddress}`);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
const tmpRecordLookupColumn = tmpClause.ExternalFilterTableLookupColumn || `ID${tmpClause.ExternalFilterByTable}`;
|
|
255
|
+
const tmpRecordIndexToRemove = tmpClause.SelectedValues.findIndex((r) => r[tmpRecordLookupColumn] == pRecordLookupValue);
|
|
256
|
+
if (tmpRecordIndexToRemove < 0)
|
|
257
|
+
{
|
|
258
|
+
this.pict.log.error(`[Filter-ExternalJoinSelectedValueList] No record found to remove for value: ${pRecordLookupValue}`);
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
const tmpRecordToRemove = tmpClause.SelectedValues.splice(tmpRecordIndexToRemove, 1)[0];
|
|
262
|
+
const tmpValue = tmpRecordToRemove[tmpRecordLookupColumn];
|
|
263
|
+
tmpClause.Values = tmpClause.Values.filter((pV) => pV !== tmpValue);
|
|
264
|
+
const tmpRecord = Object.assign({ ClauseAddress: pClauseInformaryAddress }, tmpClause);
|
|
265
|
+
this.prepareRecord(tmpRecord);
|
|
266
|
+
const tmpDestinationAddress = `#PRSP_Filter_Container_${pClauseHash}`;
|
|
267
|
+
this.render(null, tmpDestinationAddress, tmpRecord);
|
|
268
|
+
if (tmpClause.LoadMoreEnabled)
|
|
269
|
+
{
|
|
270
|
+
this.pict.ContentAssignment.removeClass(`#PRSP_Filter_${tmpClause.Hash}_Button_LoadMore`, 'is-hidden');
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
module.exports = ViewRecordSetSUBSETFilterExternalJoinSelectedValueList;
|
|
276
|
+
|
|
277
|
+
module.exports.default_configuration = Object.assign({}, ViewRecordSetSUBSETFilterExternalJoinSelectedValueList.default_configuration, _DEFAULT_CONFIGURATION_Filter_ExternalJoin_SelectedValueList);
|