@genesislcap/grid-pro 14.323.0 → 14.324.0
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/README.md +1 -1
- package/dist/custom-elements.json +941 -349
- package/dist/dts/datasource/base.datasource.d.ts +64 -5
- package/dist/dts/datasource/base.datasource.d.ts.map +1 -1
- package/dist/dts/datasource/base.types.d.ts +5 -2
- package/dist/dts/datasource/base.types.d.ts.map +1 -1
- package/dist/dts/datasource/datasource.types.d.ts +8 -0
- package/dist/dts/datasource/datasource.types.d.ts.map +1 -1
- package/dist/dts/datasource/server-side.datasource.d.ts +9 -1
- package/dist/dts/datasource/server-side.datasource.d.ts.map +1 -1
- package/dist/dts/datasource/server-side.resource-base.d.ts +26 -2
- package/dist/dts/datasource/server-side.resource-base.d.ts.map +1 -1
- package/dist/dts/datasource/server-side.resource-dataserver.d.ts +5 -0
- package/dist/dts/datasource/server-side.resource-dataserver.d.ts.map +1 -1
- package/dist/dts/datasource/server-side.resource-reqrep.d.ts +9 -0
- package/dist/dts/datasource/server-side.resource-reqrep.d.ts.map +1 -1
- package/dist/dts/grid-pro-genesis-datasource/grid-pro-genesis-datasource.d.ts +2 -0
- package/dist/dts/grid-pro-genesis-datasource/grid-pro-genesis-datasource.d.ts.map +1 -1
- package/dist/dts/status-bar-components/pagination.status-bar.d.ts.map +1 -1
- package/dist/esm/datasource/base.datasource.js +61 -19
- package/dist/esm/datasource/server-side.datasource.js +32 -44
- package/dist/esm/datasource/server-side.resource-base.js +36 -38
- package/dist/esm/datasource/server-side.resource-dataserver.js +47 -1
- package/dist/esm/datasource/server-side.resource-reqrep.js +174 -39
- package/dist/esm/grid-pro-genesis-datasource/grid-pro-genesis-datasource.js +40 -2
- package/dist/esm/status-bar-components/pagination.status-bar.js +29 -4
- package/dist/grid-pro.api.json +82 -21
- package/dist/grid-pro.d.ts +83 -6
- package/docs/api/grid-pro.genesisgriddatasourceelement.criteria.md +2 -0
- package/docs/api/grid-pro.genesisgriddatasourceelement.disablepolling.md +7 -0
- package/docs/api/grid-pro.genesisgriddatasourceelement.fields.md +7 -0
- package/docs/api/grid-pro.genesisgriddatasourceelement.issnapshot.md +7 -0
- package/docs/api/grid-pro.genesisgriddatasourceelement.maxrows.md +7 -0
- package/docs/api/grid-pro.genesisgriddatasourceelement.maxview.md +7 -0
- package/docs/api/grid-pro.genesisgriddatasourceelement.md +47 -0
- package/docs/api/grid-pro.genesisgriddatasourceelement.movingview.md +7 -0
- package/docs/api/grid-pro.genesisgriddatasourceelement.offset.md +18 -0
- package/docs/api/grid-pro.genesisgriddatasourceelement.orderby.md +7 -0
- package/docs/api/grid-pro.genesisgriddatasourceelement.pollinginterval.md +7 -0
- package/docs/api/grid-pro.genesisgriddatasourceelement.polltriggerevents.md +7 -0
- package/docs/api/grid-pro.genesisgriddatasourceelement.request.md +7 -0
- package/docs/api/grid-pro.genesisgriddatasourceelement.resourcename.md +7 -0
- package/docs/api/grid-pro.genesisgriddatasourceelement.reverse.md +7 -0
- package/docs/api/grid-pro.genesisgriddatasourceelement.viewnumber.md +2 -0
- package/docs/api/grid-pro.gridproserversidedatasource.md +3 -5
- package/docs/api/grid-pro.gridproserversidedatasource.pagingmode.md +21 -0
- package/docs/api/grid-pro.md +11 -0
- package/docs/api/grid-pro.pagingmode.md +18 -0
- package/docs/api-report.md.api.md +5 -16
- package/package.json +13 -13
- package/docs/api/grid-pro.gridproserversidedatasource.params.md +0 -14
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { __awaiter, __decorate } from "tslib";
|
|
2
2
|
import { Events, } from '@ag-grid-community/core';
|
|
3
|
-
import { dataServerResultFilter, MessageType, normaliseCriteria, toFieldMetadata, } from '@genesislcap/foundation-comms';
|
|
3
|
+
import { dataServerResultFilter, MessageType, normaliseCriteria, ResourceType, toFieldMetadata, } from '@genesislcap/foundation-comms';
|
|
4
4
|
import { LifecycleMixin, insertDocumentCSSRule } from '@genesislcap/foundation-utils';
|
|
5
5
|
import { attr, customElement, DOM, observable } from '@microsoft/fast-element';
|
|
6
6
|
import { gridProGenesisDatasourceEventNames } from '../grid-pro-genesis-datasource';
|
|
@@ -11,7 +11,6 @@ import { DataserverServerSideDatasource } from './server-side.resource-dataserve
|
|
|
11
11
|
import { ReqRepServerSideDatasource } from './server-side.resource-reqrep';
|
|
12
12
|
const criteriaDelimiter = ';';
|
|
13
13
|
const withoutColumnDefs = null;
|
|
14
|
-
const timeoutInMs = 500;
|
|
15
14
|
/**
|
|
16
15
|
* Custom CSS for server-side datasource sort indicators
|
|
17
16
|
* Makes sort indicators always visible with custom styling
|
|
@@ -203,7 +202,7 @@ let GridProServerSideDatasource = class GridProServerSideDatasource extends Life
|
|
|
203
202
|
if (!params.data) {
|
|
204
203
|
return null;
|
|
205
204
|
}
|
|
206
|
-
return params.data[this.rowId];
|
|
205
|
+
return String(params.data[this.rowId]);
|
|
207
206
|
}, getRowStyle(params) {
|
|
208
207
|
var _a, _b;
|
|
209
208
|
if ((_b = (_a = params.data) === null || _a === void 0 ? void 0 : _a.ROW_REF) === null || _b === void 0 ? void 0 : _b.includes('_deleted')) {
|
|
@@ -237,7 +236,7 @@ let GridProServerSideDatasource = class GridProServerSideDatasource extends Life
|
|
|
237
236
|
reloadResourceDataFunc: this.reloadResourceData.bind(this),
|
|
238
237
|
errorHandlerFunc: this.handleErrors.bind(this),
|
|
239
238
|
resourceName: this.resourceName,
|
|
240
|
-
resourceParams: this.
|
|
239
|
+
resourceParams: this.datasource.dataserverOnlyParams,
|
|
241
240
|
resourceIndexes: this.indexes,
|
|
242
241
|
resourceColDefs: this.datasource.originalFieldDef,
|
|
243
242
|
maxRows: +this.maxRows,
|
|
@@ -245,6 +244,8 @@ let GridProServerSideDatasource = class GridProServerSideDatasource extends Life
|
|
|
245
244
|
rowId: this.rowId,
|
|
246
245
|
pagination: this.pagination,
|
|
247
246
|
zeroBasedViewNumber: this.zeroBasedViewNumber,
|
|
247
|
+
pagingMode: this.pagingMode,
|
|
248
|
+
criteriaOnlyRequest: this.datasource.criteriaOnlyRequest,
|
|
248
249
|
});
|
|
249
250
|
}
|
|
250
251
|
else {
|
|
@@ -253,7 +254,7 @@ let GridProServerSideDatasource = class GridProServerSideDatasource extends Life
|
|
|
253
254
|
reloadResourceDataFunc: this.reloadResourceData.bind(this),
|
|
254
255
|
errorHandlerFunc: this.handleErrors.bind(this),
|
|
255
256
|
resourceName: this.resourceName,
|
|
256
|
-
resourceParams: this.
|
|
257
|
+
resourceParams: this.datasource.requestOnlyParams,
|
|
257
258
|
resourceIndexes: this.indexes,
|
|
258
259
|
resourceColDefs: this.datasource.originalFieldDef,
|
|
259
260
|
maxRows: +this.maxRows,
|
|
@@ -323,27 +324,6 @@ let GridProServerSideDatasource = class GridProServerSideDatasource extends Life
|
|
|
323
324
|
});
|
|
324
325
|
return resourceIndexesMap;
|
|
325
326
|
}
|
|
326
|
-
get params() {
|
|
327
|
-
const params = {
|
|
328
|
-
CRITERIA_MATCH: this.criteria,
|
|
329
|
-
FIELDS: this.fields,
|
|
330
|
-
MAX_ROWS: this.maxRows,
|
|
331
|
-
MAX_VIEW: this.maxView,
|
|
332
|
-
MOVING_VIEW: this.movingView,
|
|
333
|
-
REVERSE: this.reverse,
|
|
334
|
-
};
|
|
335
|
-
const keys = Array.from(this.indexes.keys());
|
|
336
|
-
if (this.orderBy) {
|
|
337
|
-
if (keys.findIndex((key) => key === this.orderBy) > -1) {
|
|
338
|
-
params.ORDER_BY = this.orderBy;
|
|
339
|
-
}
|
|
340
|
-
else {
|
|
341
|
-
const validIndexes = keys.map((key) => key);
|
|
342
|
-
logger.warn('Specified [orderBy] index is not valid and will not be used. See https://learn.genesis.global/docs/database/data-types/index-entities/ - Available indexes:', validIndexes);
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
return params;
|
|
346
|
-
}
|
|
347
327
|
get rowModel() {
|
|
348
328
|
return this.agGrid.gridApi.getModel();
|
|
349
329
|
}
|
|
@@ -357,7 +337,7 @@ let GridProServerSideDatasource = class GridProServerSideDatasource extends Life
|
|
|
357
337
|
return __awaiter(this, arguments, void 0, function* (existingParams = null) {
|
|
358
338
|
if (this.liveUpdates) {
|
|
359
339
|
const streamOnMessage = (message) => __awaiter(this, void 0, void 0, function* () {
|
|
360
|
-
var _a, _b;
|
|
340
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
361
341
|
const messageType = message.MESSAGE_TYPE;
|
|
362
342
|
if (messageType === MessageType.QUERY_UPDATE && message.ROW) {
|
|
363
343
|
if (!this.ssrmDatasource) {
|
|
@@ -369,21 +349,19 @@ let GridProServerSideDatasource = class GridProServerSideDatasource extends Life
|
|
|
369
349
|
this.handleStreamUpdates(nextMessage.updates);
|
|
370
350
|
this.handleStreamDeletes(nextMessage.deletes);
|
|
371
351
|
if (message.SEQUENCE_ID > 1) {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
352
|
+
// Calculate net row count change (inserts - deletes)
|
|
353
|
+
const netRowChange = ((_b = (_a = nextMessage.inserts) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) - ((_d = (_c = nextMessage.deletes) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0);
|
|
354
|
+
this.ssrmDatasource.serverRowsCount += netRowChange;
|
|
355
|
+
const loadedDeletes = (_f = (_e = nextMessage.deletes) === null || _e === void 0 ? void 0 : _e.filter((deleteData) => {
|
|
356
|
+
const rowId = deleteData[this.rowId];
|
|
357
|
+
const rowNode = this.agGrid.gridApi.getRowNode(rowId);
|
|
358
|
+
return rowNode != null;
|
|
359
|
+
})) !== null && _f !== void 0 ? _f : [];
|
|
360
|
+
// Calculate net row count change for client (inserts - loaded deletes)
|
|
361
|
+
const clientNetRowChange = ((_h = (_g = nextMessage.inserts) === null || _g === void 0 ? void 0 : _g.length) !== null && _h !== void 0 ? _h : 0) - loadedDeletes.length;
|
|
362
|
+
this.ssrmDatasource.clientRowsCount += clientNetRowChange;
|
|
379
363
|
this.applyAllAgTransactions();
|
|
380
364
|
}
|
|
381
|
-
else {
|
|
382
|
-
// TODO: Double-check this bit / DOM.queueUpdate do not work here
|
|
383
|
-
setTimeout(() => {
|
|
384
|
-
this.applyAllAgTransactions();
|
|
385
|
-
}, timeoutInMs);
|
|
386
|
-
}
|
|
387
365
|
}
|
|
388
366
|
});
|
|
389
367
|
const onError = (error) => {
|
|
@@ -392,7 +370,7 @@ let GridProServerSideDatasource = class GridProServerSideDatasource extends Life
|
|
|
392
370
|
this.handleErrors(((_a = error.receivedMessage) === null || _a === void 0 ? void 0 : _a.ERROR) || error.message, 'stream');
|
|
393
371
|
};
|
|
394
372
|
this.liveUpdatesStream = this.connect
|
|
395
|
-
.stream(this.resourceName, () => { }, onError, existingParams !== null && existingParams !== void 0 ? existingParams : this.
|
|
373
|
+
.stream(this.resourceName, () => { }, onError, existingParams !== null && existingParams !== void 0 ? existingParams : this.datasource.dataserverOnlyParams)
|
|
396
374
|
.subscribe((message) => streamOnMessage(message));
|
|
397
375
|
// return this.connect.stream(
|
|
398
376
|
// this.resourceName,
|
|
@@ -417,9 +395,16 @@ let GridProServerSideDatasource = class GridProServerSideDatasource extends Life
|
|
|
417
395
|
getAgColumnDefs(fieldsMetadata) {
|
|
418
396
|
return __awaiter(this, void 0, void 0, function* () {
|
|
419
397
|
const colDefsFromGenesisData = this.generateColumnDefsFromMetadata(fieldsMetadata, getServerSideFilterParamsByFieldType);
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
398
|
+
if (this.datasource.resourceType === ResourceType.DATASERVER) {
|
|
399
|
+
colDefsFromGenesisData.forEach((colDef) => {
|
|
400
|
+
colDef.sortable = [].concat(...this.indexes.values()).includes(colDef.field);
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
else {
|
|
404
|
+
colDefsFromGenesisData.forEach((colDef) => {
|
|
405
|
+
colDef.sortable = true;
|
|
406
|
+
});
|
|
407
|
+
}
|
|
423
408
|
const colDefsMergedWithTemplateDefs = yield this.agGrid.mergeAllColumnDefsAndStates(colDefsFromGenesisData, true);
|
|
424
409
|
return colDefsMergedWithTemplateDefs;
|
|
425
410
|
});
|
|
@@ -440,6 +425,9 @@ __decorate([
|
|
|
440
425
|
__decorate([
|
|
441
426
|
attr({ mode: 'boolean', attribute: 'live-updates' })
|
|
442
427
|
], GridProServerSideDatasource.prototype, "liveUpdates", void 0);
|
|
428
|
+
__decorate([
|
|
429
|
+
attr({ attribute: 'paging-mode' })
|
|
430
|
+
], GridProServerSideDatasource.prototype, "pagingMode", void 0);
|
|
443
431
|
__decorate([
|
|
444
432
|
observable
|
|
445
433
|
], GridProServerSideDatasource.prototype, "request", void 0);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { __awaiter, __decorate } from "tslib";
|
|
2
2
|
import { Auth, Connect, logger, } from '@genesislcap/foundation-comms';
|
|
3
3
|
import { UUID } from '@genesislcap/foundation-utils';
|
|
4
|
-
import { getAvailableIndexes, getAvailableIndexFields } from '../utils';
|
|
5
4
|
/**
|
|
6
5
|
* Base class for server-side resource datasources used in Grid Pro SSRM implementations.
|
|
7
6
|
* Provides common logic for filtering, sorting, and pagination.
|
|
@@ -10,6 +9,7 @@ import { getAvailableIndexes, getAvailableIndexFields } from '../utils';
|
|
|
10
9
|
*/
|
|
11
10
|
export class BaseServerSideDatasource {
|
|
12
11
|
constructor(options) {
|
|
12
|
+
var _a;
|
|
13
13
|
this.rowData = new Map();
|
|
14
14
|
/**
|
|
15
15
|
* The number of rows in the grid. THIS DO NOT CONSIDER CRITERIA_MATCH scenarios.
|
|
@@ -36,13 +36,18 @@ export class BaseServerSideDatasource {
|
|
|
36
36
|
this.rowId = options.rowId;
|
|
37
37
|
this.pagination = options.pagination;
|
|
38
38
|
this.zeroBasedViewNumber = options.zeroBasedViewNumber;
|
|
39
|
+
this.pagingMode = options.pagingMode;
|
|
40
|
+
this.criteriaOnlyRequest = (_a = options.criteriaOnlyRequest) !== null && _a !== void 0 ? _a : false;
|
|
39
41
|
}
|
|
40
42
|
getRows(params) {
|
|
41
43
|
throw new Error('Method not implemented.');
|
|
42
44
|
}
|
|
43
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Handles filtering setup for server-side datasources.
|
|
47
|
+
* Common logic used by both dataserver and req-rep implementations.
|
|
48
|
+
*/
|
|
49
|
+
setupFiltering(params) {
|
|
44
50
|
return __awaiter(this, void 0, void 0, function* () {
|
|
45
|
-
var _a;
|
|
46
51
|
const filterModelBeingApplied = params.request.filterModel;
|
|
47
52
|
const filtersAreBeingApplied = Object.keys(filterModelBeingApplied).length > 0;
|
|
48
53
|
const filtersAreGettingCleaned = Object.keys(filterModelBeingApplied).length === 0;
|
|
@@ -61,40 +66,17 @@ export class BaseServerSideDatasource {
|
|
|
61
66
|
return;
|
|
62
67
|
}
|
|
63
68
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
else if (toBeAppliedSortModel.length > 0) {
|
|
76
|
-
const coldIdBeingSorted = toBeAppliedSortModel[0].colId; // Not allowing multiple sorts by user
|
|
77
|
-
const sortTypeBeingApplied = toBeAppliedSortModel[0].sort;
|
|
78
|
-
const orderByAndToBeSortedColIds = this.getOrderByAndToBeSortedColIds(this.resourceIndexes, coldIdBeingSorted);
|
|
79
|
-
if (!orderByAndToBeSortedColIds) {
|
|
80
|
-
this.calculatedRowsCount = 0;
|
|
81
|
-
const availableIndexes = getAvailableIndexes(this.resourceIndexes);
|
|
82
|
-
const availableIndexFields = getAvailableIndexFields(this.resourceIndexes);
|
|
83
|
-
logger.warn('The FIELD/column (${coldIdBeingSorted}) being sorted is not part of an INDEX, required for the [orderBy] operation. See https://learn.genesis.global/docs/database/data-types/index-entities/');
|
|
84
|
-
logger.debug('Available indexes:', availableIndexes);
|
|
85
|
-
logger.debug('Columns that can be sorted with the available indexes:', availableIndexFields);
|
|
86
|
-
params.fail();
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
else if (JSON.stringify(toBeAppliedSortModel) !== JSON.stringify(this.currentSortModel)) {
|
|
90
|
-
this.currentSortModel = toBeAppliedSortModel;
|
|
91
|
-
this.resourceParams.ORDER_BY = orderByAndToBeSortedColIds.orderBy;
|
|
92
|
-
this.resourceParams.REVERSE = sortTypeBeingApplied === 'desc' ? true : false;
|
|
93
|
-
yield this.refreshDatasource(params);
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Legacy method that combines filtering and sorting.
|
|
73
|
+
* Kept for backward compatibility. New implementations should use setupFiltering and setupSorting directly.
|
|
74
|
+
* @deprecated Use setupFiltering() and setupSorting() separately instead
|
|
75
|
+
*/
|
|
76
|
+
setupFilteringAndSorting(params) {
|
|
77
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
78
|
+
yield this.setupFiltering(params);
|
|
79
|
+
yield this.setupSorting(params);
|
|
98
80
|
});
|
|
99
81
|
}
|
|
100
82
|
destroy() {
|
|
@@ -245,7 +227,7 @@ export class BaseServerSideDatasource {
|
|
|
245
227
|
.filter((k) => this.currentFilterModel[k].filterType === filterType);
|
|
246
228
|
}
|
|
247
229
|
getPageNumber(start, recordsPerPage, totalRecords, zeroBasedViewNumber = true) {
|
|
248
|
-
if (start > totalRecords) {
|
|
230
|
+
if (totalRecords !== undefined && start > totalRecords) {
|
|
249
231
|
start = Math.floor((totalRecords - 1) / recordsPerPage) * recordsPerPage + 1;
|
|
250
232
|
}
|
|
251
233
|
const currentPageIndex = Math.ceil(start / recordsPerPage);
|
|
@@ -280,6 +262,22 @@ export class BaseServerSideDatasource {
|
|
|
280
262
|
get isNotFirstViewNumber() {
|
|
281
263
|
return this.zeroBasedViewNumber ? this.currentSequenceId > 0 : this.currentSequenceId > 1;
|
|
282
264
|
}
|
|
265
|
+
/**
|
|
266
|
+
* Determines the effective paging mode based on criteriaOnlyRequest availability and user settings
|
|
267
|
+
*/
|
|
268
|
+
getEffectivePagingMode() {
|
|
269
|
+
// If user explicitly set a paging mode
|
|
270
|
+
if (this.pagingMode) {
|
|
271
|
+
// If criteriaOnlyRequest is not available but user wants offsetBased, warn and use viewBased
|
|
272
|
+
if (this.pagingMode === 'offsetBased' && !this.criteriaOnlyRequest) {
|
|
273
|
+
logger.warn('offsetBased paging mode requires criteriaOnlyRequest support. Falling back to viewBased mode.');
|
|
274
|
+
return 'viewBased';
|
|
275
|
+
}
|
|
276
|
+
return this.pagingMode;
|
|
277
|
+
}
|
|
278
|
+
// Auto-determine based on criteriaOnlyRequest availability
|
|
279
|
+
return this.criteriaOnlyRequest ? 'offsetBased' : 'viewBased';
|
|
280
|
+
}
|
|
283
281
|
}
|
|
284
282
|
__decorate([
|
|
285
283
|
Auth
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { __awaiter } from "tslib";
|
|
2
2
|
import { MessageType, dataServerResultFilter, logger, } from '@genesislcap/foundation-comms';
|
|
3
3
|
import { DOM } from '@microsoft/fast-element';
|
|
4
|
+
import { getAvailableIndexes, getAvailableIndexFields } from '../utils';
|
|
4
5
|
import { BaseServerSideDatasource } from './server-side.resource-base';
|
|
5
6
|
/**
|
|
6
7
|
* The DATASERVER IServerSideDatasource implementation, used for SSRM (Server-Side Row Model) in the grid.
|
|
@@ -24,7 +25,9 @@ export class DataserverServerSideDatasource extends BaseServerSideDatasource {
|
|
|
24
25
|
}
|
|
25
26
|
getRows(params) {
|
|
26
27
|
return __awaiter(this, void 0, void 0, function* () {
|
|
27
|
-
|
|
28
|
+
// Use separated filtering and sorting setup
|
|
29
|
+
yield this.setupFiltering(params);
|
|
30
|
+
yield this.setupSorting(params);
|
|
28
31
|
if (this.pagination && !this.isNewPageSize && this.currentSequenceId > 0) {
|
|
29
32
|
params.success(this.lastSuccessRowData);
|
|
30
33
|
return;
|
|
@@ -115,6 +118,49 @@ export class DataserverServerSideDatasource extends BaseServerSideDatasource {
|
|
|
115
118
|
this.lastSuccessRowData = successRowData;
|
|
116
119
|
params.success(successRowData);
|
|
117
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Dataserver-specific sorting setup that validates columns are part of an index.
|
|
123
|
+
* This is required because dataserver needs indexed columns for efficient sorting.
|
|
124
|
+
*/
|
|
125
|
+
setupSorting(params) {
|
|
126
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
127
|
+
var _a;
|
|
128
|
+
const toBeAppliedSortModel = params.request.sortModel;
|
|
129
|
+
if (((_a = this.currentSortModel) === null || _a === void 0 ? void 0 : _a.length) !== toBeAppliedSortModel.length ||
|
|
130
|
+
toBeAppliedSortModel.length > 0) {
|
|
131
|
+
if (toBeAppliedSortModel.length === 0 && this.currentSortModel) {
|
|
132
|
+
this.calculatedRowsCount = 0;
|
|
133
|
+
this.currentSortModel = null;
|
|
134
|
+
this.resourceParams.ORDER_BY = null;
|
|
135
|
+
this.resourceParams.REVERSE = null;
|
|
136
|
+
yield this.refreshDatasource(params);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
else if (toBeAppliedSortModel.length > 0) {
|
|
140
|
+
const coldIdBeingSorted = toBeAppliedSortModel[0].colId; // Not allowing multiple sorts by user
|
|
141
|
+
const sortTypeBeingApplied = toBeAppliedSortModel[0].sort;
|
|
142
|
+
const orderByAndToBeSortedColIds = this.getOrderByAndToBeSortedColIds(this.resourceIndexes, coldIdBeingSorted);
|
|
143
|
+
if (!orderByAndToBeSortedColIds) {
|
|
144
|
+
this.calculatedRowsCount = 0;
|
|
145
|
+
const availableIndexes = getAvailableIndexes(this.resourceIndexes);
|
|
146
|
+
const availableIndexFields = getAvailableIndexFields(this.resourceIndexes);
|
|
147
|
+
logger.warn(`The FIELD/column (${coldIdBeingSorted}) being sorted is not part of an INDEX, required for the [orderBy] operation. See https://learn.genesis.global/docs/database/data-types/index-entities/`);
|
|
148
|
+
logger.debug('Available indexes:', availableIndexes);
|
|
149
|
+
logger.debug('Columns that can be sorted with the available indexes:', availableIndexFields);
|
|
150
|
+
params.fail();
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
else if (JSON.stringify(toBeAppliedSortModel) !== JSON.stringify(this.currentSortModel)) {
|
|
154
|
+
this.currentSortModel = toBeAppliedSortModel;
|
|
155
|
+
this.resourceParams.ORDER_BY = orderByAndToBeSortedColIds.orderBy;
|
|
156
|
+
this.resourceParams.REVERSE = sortTypeBeingApplied === 'desc' ? true : false;
|
|
157
|
+
yield this.refreshDatasource(params);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
}
|
|
118
164
|
destroy() {
|
|
119
165
|
const _super = Object.create(null, {
|
|
120
166
|
destroy: { get: () => super.destroy }
|
|
@@ -10,41 +10,84 @@ export class ReqRepServerSideDatasource extends BaseServerSideDatasource {
|
|
|
10
10
|
constructor(options) {
|
|
11
11
|
var _a;
|
|
12
12
|
super(options);
|
|
13
|
+
// Track the total discovered row count when we reach the last page
|
|
14
|
+
this.discoveredTotalRowCount = null;
|
|
15
|
+
this.currentNextOffset = 0;
|
|
13
16
|
this.createReqRepRequestFunc = options.createReqRepRequestFunc;
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
const effectivePagingMode = this.getEffectivePagingMode();
|
|
18
|
+
// Initialize based on paging mode
|
|
19
|
+
if (effectivePagingMode === 'viewBased') {
|
|
20
|
+
if (!((_a = options.resourceParams) === null || _a === void 0 ? void 0 : _a.VIEW_NUMBER)) {
|
|
21
|
+
this.resourceParams.VIEW_NUMBER = this.zeroBasedViewNumber ? 0 : 1;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
// offsetBased
|
|
26
|
+
if (!options.resourceParams.OFFSET) {
|
|
27
|
+
this.resourceParams.OFFSET = 0;
|
|
28
|
+
}
|
|
16
29
|
}
|
|
17
30
|
}
|
|
18
31
|
getRows(params) {
|
|
19
32
|
return __awaiter(this, void 0, void 0, function* () {
|
|
20
33
|
var _a;
|
|
21
|
-
|
|
34
|
+
// Use custom filtering and sorting setup for req-rep
|
|
35
|
+
yield this.setupFiltering(params);
|
|
36
|
+
yield this.setupSorting(params);
|
|
22
37
|
if (this.pagination && !this.isNewPageSize && this.currentSequenceId > 0) {
|
|
23
38
|
params.success(this.lastSuccessRowData);
|
|
24
39
|
return;
|
|
25
40
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
41
|
+
const effectivePagingMode = this.getEffectivePagingMode();
|
|
42
|
+
if (effectivePagingMode === 'viewBased') {
|
|
43
|
+
if (this.currentSequenceId !== null && this.currentSequenceId >= 0 && this.moreRows) {
|
|
44
|
+
if (this.pagination) {
|
|
45
|
+
this.resourceParams.VIEW_NUMBER = this.getPageNumber(params.request.startRow, this.maxRows, undefined, // Don't pass maxView as totalRecords since it's not a valid total count
|
|
46
|
+
this.zeroBasedViewNumber);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
this.resourceParams.VIEW_NUMBER += 1;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
// offsetBased
|
|
55
|
+
if (this.currentNextOffset > 0 && this.currentNextOffset !== params.request.startRow) {
|
|
56
|
+
this.resourceParams.OFFSET = this.currentNextOffset;
|
|
29
57
|
}
|
|
30
58
|
else {
|
|
31
|
-
this.resourceParams.
|
|
59
|
+
this.resourceParams.OFFSET = params.request.startRow;
|
|
32
60
|
}
|
|
33
61
|
}
|
|
34
62
|
const requestParams = {
|
|
35
|
-
DETAILS:
|
|
36
|
-
CRITERIA_MATCH: this.resourceParams.CRITERIA_MATCH,
|
|
37
|
-
MAX_ROWS: this.resourceParams.MAX_ROWS,
|
|
38
|
-
VIEW_NUMBER: this.resourceParams.VIEW_NUMBER,
|
|
39
|
-
},
|
|
63
|
+
DETAILS: this.buildRequestDetails(effectivePagingMode),
|
|
40
64
|
};
|
|
41
65
|
const requestResult = yield this.createReqRepRequestFunc(requestParams);
|
|
42
|
-
//
|
|
66
|
+
// Check if MORE_ROWS is available in the response (GSF 8.14+ only)
|
|
67
|
+
const hasMoreRowsInResult = 'MORE_ROWS' in requestResult;
|
|
43
68
|
let isLastView = false;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
69
|
+
// Fall back to the existing logic for backwards compatibility
|
|
70
|
+
if (effectivePagingMode === 'viewBased') {
|
|
71
|
+
// Massive limitation on the GSF. It should return -1 if it's already the last view/record (but it doesn't, next will have 0 rows then the NEXT_VIEW=-1).
|
|
72
|
+
if (hasMoreRowsInResult) {
|
|
73
|
+
// Only works with GSF 8.14+
|
|
74
|
+
isLastView = !requestResult.MORE_ROWS;
|
|
75
|
+
}
|
|
76
|
+
else if (requestResult.NEXT_VIEW !== -1) {
|
|
77
|
+
const preCheckRequestParams = Object.assign(Object.assign({}, requestParams), { DETAILS: Object.assign(Object.assign({}, requestParams.DETAILS), { VIEW_NUMBER: requestResult.NEXT_VIEW }) });
|
|
78
|
+
const moreRowsPreCheck = yield this.createReqRepRequestFunc(preCheckRequestParams);
|
|
79
|
+
isLastView = moreRowsPreCheck.NEXT_VIEW === -1 && ((_a = moreRowsPreCheck.REPLY) === null || _a === void 0 ? void 0 : _a.length) === 0;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
// offsetBased: check if NEXT_OFFSET exists and is valid
|
|
84
|
+
isLastView = hasMoreRowsInResult && !requestResult.MORE_ROWS;
|
|
85
|
+
if ('NEXT_OFFSET' in requestResult && requestResult.NEXT_OFFSET !== -1) {
|
|
86
|
+
this.currentNextOffset = requestResult.NEXT_OFFSET;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
this.currentNextOffset = 0;
|
|
90
|
+
}
|
|
48
91
|
}
|
|
49
92
|
let applyResult = true;
|
|
50
93
|
if (applyResult) {
|
|
@@ -54,7 +97,7 @@ export class ReqRepServerSideDatasource extends BaseServerSideDatasource {
|
|
|
54
97
|
});
|
|
55
98
|
}
|
|
56
99
|
applyServerSideData(params, result, isLastView) {
|
|
57
|
-
var _a;
|
|
100
|
+
var _a, _b;
|
|
58
101
|
const messageType = result.MESSAGE_TYPE;
|
|
59
102
|
if (messageType &&
|
|
60
103
|
(messageType === MessageType.LOGOFF_ACK || messageType === MessageType.MSG_NACK)) {
|
|
@@ -68,8 +111,27 @@ export class ReqRepServerSideDatasource extends BaseServerSideDatasource {
|
|
|
68
111
|
params.fail();
|
|
69
112
|
return;
|
|
70
113
|
}
|
|
71
|
-
this.
|
|
72
|
-
|
|
114
|
+
const effectivePagingMode = this.getEffectivePagingMode();
|
|
115
|
+
// TODO: the code below will be tweaked/removed when gsf <8.14 is no longer supported
|
|
116
|
+
if ('MORE_ROWS' in result) {
|
|
117
|
+
this.moreRows = result.MORE_ROWS;
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
// Fall back to the existing logic for backwards compatibility
|
|
121
|
+
if (effectivePagingMode === 'viewBased') {
|
|
122
|
+
this.moreRows =
|
|
123
|
+
!isLastView &&
|
|
124
|
+
result.NEXT_VIEW !== -1 &&
|
|
125
|
+
result.NEXT_VIEW > this.resourceParams.VIEW_NUMBER;
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
// offsetBased
|
|
129
|
+
this.moreRows =
|
|
130
|
+
!isLastView &&
|
|
131
|
+
result.NEXT_OFFSET !== -1 &&
|
|
132
|
+
result.NEXT_OFFSET > this.resourceParams.OFFSET;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
73
135
|
if (result.REPLY) {
|
|
74
136
|
this.handleCurrentStreamLoad(result.REPLY);
|
|
75
137
|
}
|
|
@@ -80,9 +142,27 @@ export class ReqRepServerSideDatasource extends BaseServerSideDatasource {
|
|
|
80
142
|
params.success(successRowData);
|
|
81
143
|
return;
|
|
82
144
|
}
|
|
83
|
-
|
|
145
|
+
// Update current sequence ID based on paging mode
|
|
146
|
+
if (effectivePagingMode === 'viewBased') {
|
|
147
|
+
this.currentSequenceId = this.resourceParams.VIEW_NUMBER;
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
// For offsetBased, use OFFSET / maxRows to get the sequence
|
|
151
|
+
this.currentSequenceId = Math.floor(this.resourceParams.OFFSET / this.maxRows);
|
|
152
|
+
}
|
|
84
153
|
this.sourceRef = result.SOURCE_REF;
|
|
85
|
-
|
|
154
|
+
// For req-rep, store the total row count when we reach the last page
|
|
155
|
+
if (!this.moreRows) {
|
|
156
|
+
const currentBatchSize = this.rowData.size;
|
|
157
|
+
this.discoveredTotalRowCount = params.request.startRow + currentBatchSize;
|
|
158
|
+
}
|
|
159
|
+
// Reset serverRowsCount accumulation for req-rep pagination
|
|
160
|
+
if (this.pagination) {
|
|
161
|
+
this.serverRowsCount = (_a = result.ROWS_COUNT) !== null && _a !== void 0 ? _a : this.rowData.size;
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
this.serverRowsCount += (_b = result.ROWS_COUNT) !== null && _b !== void 0 ? _b : this.rowData.size;
|
|
165
|
+
}
|
|
86
166
|
const successRowData = {
|
|
87
167
|
rowData: Array.from(this.rowData.values()),
|
|
88
168
|
};
|
|
@@ -91,30 +171,25 @@ export class ReqRepServerSideDatasource extends BaseServerSideDatasource {
|
|
|
91
171
|
params.success(successRowData);
|
|
92
172
|
}
|
|
93
173
|
getCorrectRowCount(params) {
|
|
94
|
-
const lastRow = this.moreRows ? -1 : params.request.startRow + this.serverRowsCount;
|
|
95
|
-
const currentLastRowNumber = params.request.endRow;
|
|
96
|
-
this.calculatedRowsCount = this.serverRowsCount || currentLastRowNumber;
|
|
97
|
-
const defaultCount = Math.min(lastRow, this.maxView);
|
|
98
174
|
let rowCount;
|
|
99
175
|
if (this.pagination) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
rowCount =
|
|
176
|
+
if (this.moreRows) {
|
|
177
|
+
// More data available, return -1 to indicate unknown total
|
|
178
|
+
rowCount = -1;
|
|
103
179
|
}
|
|
104
|
-
|
|
105
|
-
|
|
180
|
+
else {
|
|
181
|
+
// Use discovered total if available, otherwise calculate from current position
|
|
182
|
+
rowCount = this.discoveredTotalRowCount || params.request.startRow + this.rowData.size;
|
|
106
183
|
}
|
|
107
184
|
return rowCount;
|
|
108
185
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
else if (currentLastRowNumber > this.maxView ||
|
|
113
|
-
currentLastRowNumber > this.calculatedRowsCount) {
|
|
114
|
-
rowCount = Math.min(defaultCount, this.calculatedRowsCount);
|
|
186
|
+
// Non-pagination mode (streaming)
|
|
187
|
+
if (this.moreRows) {
|
|
188
|
+
rowCount = -1; // More data available, unknown total
|
|
115
189
|
}
|
|
116
|
-
else
|
|
117
|
-
|
|
190
|
+
else {
|
|
191
|
+
// Use discovered total or calculate from current batch
|
|
192
|
+
rowCount = this.discoveredTotalRowCount || params.request.startRow + this.rowData.size;
|
|
118
193
|
}
|
|
119
194
|
return rowCount;
|
|
120
195
|
}
|
|
@@ -136,4 +211,64 @@ export class ReqRepServerSideDatasource extends BaseServerSideDatasource {
|
|
|
136
211
|
});
|
|
137
212
|
this.rowData = rows;
|
|
138
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* Req-rep specific sorting setup that allows any column to be sorted
|
|
216
|
+
* (unlike dataserver which requires indexed columns only)
|
|
217
|
+
*/
|
|
218
|
+
setupSorting(params) {
|
|
219
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
220
|
+
var _a;
|
|
221
|
+
const toBeAppliedSortModel = params.request.sortModel;
|
|
222
|
+
if (((_a = this.currentSortModel) === null || _a === void 0 ? void 0 : _a.length) !== toBeAppliedSortModel.length ||
|
|
223
|
+
toBeAppliedSortModel.length > 0) {
|
|
224
|
+
if (toBeAppliedSortModel.length === 0 && this.currentSortModel) {
|
|
225
|
+
this.calculatedRowsCount = 0;
|
|
226
|
+
this.currentSortModel = null;
|
|
227
|
+
this.resourceParams.ORDER_BY = undefined;
|
|
228
|
+
yield this.refreshDatasource(params);
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
else if (toBeAppliedSortModel.length > 0) {
|
|
232
|
+
const coldIdBeingSorted = toBeAppliedSortModel[0].colId; // Not allowing multiple sorts by user
|
|
233
|
+
const sortTypeBeingApplied = toBeAppliedSortModel[0].sort;
|
|
234
|
+
// For req-rep, we can sort by any column without requiring it to be part of an index
|
|
235
|
+
if (JSON.stringify(toBeAppliedSortModel) !== JSON.stringify(this.currentSortModel)) {
|
|
236
|
+
this.currentSortModel = toBeAppliedSortModel;
|
|
237
|
+
this.resourceParams.ORDER_BY =
|
|
238
|
+
coldIdBeingSorted + (sortTypeBeingApplied === 'desc' ? ' DESC' : ' ASC'); // Use the column directly
|
|
239
|
+
yield this.refreshDatasource(params);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
refreshDatasource(params) {
|
|
247
|
+
const _super = Object.create(null, {
|
|
248
|
+
refreshDatasource: { get: () => super.refreshDatasource }
|
|
249
|
+
});
|
|
250
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
251
|
+
// Reset discovered total when refreshing (sorting/filtering changes)
|
|
252
|
+
this.discoveredTotalRowCount = null;
|
|
253
|
+
this.currentNextOffset = 0;
|
|
254
|
+
// Reset pagination parameters to start from beginning
|
|
255
|
+
this.resourceParams.VIEW_NUMBER = this.zeroBasedViewNumber ? 0 : 1;
|
|
256
|
+
this.resourceParams.OFFSET = 0;
|
|
257
|
+
yield _super.refreshDatasource.call(this, params);
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
buildRequestDetails(effectivePagingMode) {
|
|
261
|
+
const baseDetails = {
|
|
262
|
+
CRITERIA_MATCH: this.resourceParams.CRITERIA_MATCH,
|
|
263
|
+
MAX_ROWS: this.resourceParams.MAX_ROWS,
|
|
264
|
+
ORDER_BY: this.resourceParams.ORDER_BY,
|
|
265
|
+
};
|
|
266
|
+
if (effectivePagingMode === 'viewBased') {
|
|
267
|
+
return Object.assign(Object.assign({}, baseDetails), { VIEW_NUMBER: this.resourceParams.VIEW_NUMBER });
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
// offsetBased
|
|
271
|
+
return Object.assign(Object.assign({}, baseDetails), { OFFSET: this.resourceParams.OFFSET });
|
|
272
|
+
}
|
|
273
|
+
}
|
|
139
274
|
}
|