@genesislcap/grid-pro 15.20.2-grid-pro-datasource-fix.1 → 15.21.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.
Files changed (47) hide show
  1. package/dist/custom-elements.json +2147 -169
  2. package/dist/dts/datasource/base.datasource.d.ts +17 -3
  3. package/dist/dts/datasource/base.datasource.d.ts.map +1 -1
  4. package/dist/dts/datasource/base.types.d.ts +1 -1
  5. package/dist/dts/datasource/base.types.d.ts.map +1 -1
  6. package/dist/dts/datasource/datasource.types.d.ts +5 -2
  7. package/dist/dts/datasource/datasource.types.d.ts.map +1 -1
  8. package/dist/dts/datasource/filter.utils.d.ts +40 -0
  9. package/dist/dts/datasource/filter.utils.d.ts.map +1 -0
  10. package/dist/dts/datasource/index.d.ts +2 -0
  11. package/dist/dts/datasource/index.d.ts.map +1 -1
  12. package/dist/dts/datasource/infinite.datasource.d.ts +464 -0
  13. package/dist/dts/datasource/infinite.datasource.d.ts.map +1 -0
  14. package/dist/dts/datasource/infinite.resource.d.ts +231 -0
  15. package/dist/dts/datasource/infinite.resource.d.ts.map +1 -0
  16. package/dist/dts/datasource/server-side.datasource.d.ts +0 -2
  17. package/dist/dts/datasource/server-side.datasource.d.ts.map +1 -1
  18. package/dist/dts/datasource/server-side.resource-base.d.ts +1 -1
  19. package/dist/dts/datasource/server-side.resource-base.d.ts.map +1 -1
  20. package/dist/dts/grid-pro-beta.d.ts +37 -8
  21. package/dist/dts/grid-pro-beta.d.ts.map +1 -1
  22. package/dist/dts/grid-pro-genesis-datasource/datasource-events.types.d.ts +20 -1
  23. package/dist/dts/grid-pro-genesis-datasource/datasource-events.types.d.ts.map +1 -1
  24. package/dist/dts/grid-pro-genesis-datasource/grid-pro-genesis-datasource.d.ts +0 -1
  25. package/dist/dts/grid-pro-genesis-datasource/grid-pro-genesis-datasource.d.ts.map +1 -1
  26. package/dist/dts/grid-pro.d.ts +6 -6
  27. package/dist/dts/grid-pro.d.ts.map +1 -1
  28. package/dist/dts/react.d.ts +25 -1
  29. package/dist/dts/utils/map.d.ts +2 -2
  30. package/dist/dts/utils/map.d.ts.map +1 -1
  31. package/dist/esm/datasource/base.datasource.js +39 -2
  32. package/dist/esm/datasource/filter.utils.js +241 -0
  33. package/dist/esm/datasource/index.js +2 -0
  34. package/dist/esm/datasource/infinite.datasource.js +373 -0
  35. package/dist/esm/datasource/infinite.resource.js +581 -0
  36. package/dist/esm/datasource/server-side.datasource.js +0 -38
  37. package/dist/esm/datasource/server-side.grid-definitions.js +1 -1
  38. package/dist/esm/datasource/server-side.resource-base.js +7 -105
  39. package/dist/esm/grid-pro-beta.js +73 -24
  40. package/dist/esm/grid-pro-genesis-datasource/datasource-events.types.js +3 -0
  41. package/dist/esm/grid-pro-genesis-datasource/grid-pro-genesis-datasource.js +0 -3
  42. package/dist/esm/grid-pro.js +12 -19
  43. package/dist/grid-pro.api.json +1355 -477
  44. package/dist/grid-pro.d.ts +958 -173
  45. package/dist/react.cjs +84 -0
  46. package/dist/react.mjs +83 -0
  47. package/package.json +13 -13
@@ -1,6 +1,7 @@
1
1
  import { __awaiter, __decorate } from "tslib";
2
2
  import { Auth, Connect } from '@genesislcap/foundation-comms';
3
3
  import { UUID } from '@genesislcap/foundation-utils';
4
+ import { convertDateFilterToCriteria, convertNumberFilterToCriteria, convertSetFilterToCriteria, convertTextFilterToCriteria, } from './filter.utils';
4
5
  /**
5
6
  * Base class for server-side resource datasources used in Grid Pro SSRM implementations.
6
7
  * Provides common logic for filtering, sorting, and infinite-scroll row counting.
@@ -240,117 +241,18 @@ export class BaseServerSideDatasource {
240
241
  }
241
242
  }
242
243
  criteriaForTextModel(k, model) {
243
- const type = model.type;
244
- const val = model.filter;
245
- if (!val && (type === 'false' || type === 'true')) {
246
- return `${k} == ${type}`;
247
- }
248
- const safeVal = val ? String(val).replace(/'/g, "\\'") : '';
249
- switch (type) {
250
- case 'blank':
251
- return `(${k} == '' || ${k} == null)`;
252
- case 'contains':
253
- return `Expr.containsIgnoreCase(${k}, '${safeVal}')`;
254
- case 'equals':
255
- return `${k} == '${safeVal}'`;
256
- case 'notBlank':
257
- return `(${k} != '' && ${k} != null)`;
258
- case 'notEqual':
259
- return `${k} != '${safeVal}'`;
260
- case 'wordStartsWith':
261
- return `Expr.containsWordsStartingWithIgnoreCase(${k}, '${safeVal}')`;
262
- default:
263
- return null;
264
- }
244
+ return convertTextFilterToCriteria(model, k);
265
245
  }
266
246
  criteriaForSetModel(k, model) {
267
- var _a, _b;
268
- const selectedValues = ((_a = model.values) !== null && _a !== void 0 ? _a : []);
269
- if (!selectedValues.length) {
270
- // Nothing selected means no additional criteria
271
- return null;
272
- }
273
- // Try to detect "all values selected" using VALID_VALUES from metadata.
274
- // In that case we don't want to send any criteria, as it would be equivalent
275
- // to no filter at all.
276
- const colMeta = (_b = this.resourceColDefs) === null || _b === void 0 ? void 0 : _b.find((o) => o.NAME === k);
277
- let allValues;
278
- if (colMeta === null || colMeta === void 0 ? void 0 : colMeta.VALID_VALUES) {
279
- try {
280
- allValues = Array.isArray(colMeta.VALID_VALUES)
281
- ? colMeta.VALID_VALUES
282
- : colMeta.VALID_VALUES.split('|');
283
- }
284
- catch (_c) {
285
- allValues = undefined;
286
- }
287
- }
288
- if (allValues &&
289
- allValues.length === selectedValues.length &&
290
- allValues.every((v) => selectedValues.includes(v))) {
291
- // All enum options are selected – skip adding criteria for this column
292
- return null;
293
- }
294
- const orConditions = selectedValues.map((val) => {
295
- const safeVal = String(val).replace(/'/g, "\\'");
296
- return `${k} == '${safeVal}'`;
297
- });
298
- return orConditions.length ? `(${orConditions.join(' || ')})` : null;
247
+ var _a;
248
+ const colMeta = (_a = this.resourceColDefs) === null || _a === void 0 ? void 0 : _a.find((o) => o.NAME === k);
249
+ return convertSetFilterToCriteria(model, k, colMeta);
299
250
  }
300
251
  criteriaForNumberModel(k, model) {
301
- const value = model.filter;
302
- const valueTwo = model.filterTo;
303
- const isNum = (v) => v !== null && v !== '' && !isNaN(Number(v));
304
- switch (model.type) {
305
- case 'equals':
306
- return isNum(value) ? `${k} == ${value}` : null;
307
- case 'notEqual':
308
- return isNum(value) ? `${k} != ${value}` : null;
309
- case 'greaterThan':
310
- return isNum(value) ? `${k} > ${value}` : null;
311
- case 'greaterThanOrEqual':
312
- return isNum(value) ? `${k} >= ${value}` : null;
313
- case 'lessThan':
314
- return isNum(value) ? `${k} < ${value}` : null;
315
- case 'lessThanOrEqual':
316
- return isNum(value) ? `${k} <= ${value}` : null;
317
- case 'inRange':
318
- return isNum(value) && isNum(valueTwo) ? `${k} >= ${value} && ${k} <= ${valueTwo}` : null;
319
- case 'blank':
320
- return `${k} == 0`;
321
- case 'notBlank':
322
- return `${k} != 0`;
323
- default:
324
- return null;
325
- }
252
+ return convertNumberFilterToCriteria(model, k);
326
253
  }
327
254
  criteriaForDateModel(k, model) {
328
- var _a, _b;
329
- const dateFrom = (_a = model.dateFrom) === null || _a === void 0 ? void 0 : _a.replace(/-/g, '').replace('T', '-').split(' ')[0];
330
- const dateTo = (_b = model.dateTo) === null || _b === void 0 ? void 0 : _b.replace(/-/g, '').replace('T', '-').split(' ')[0];
331
- switch (model.type) {
332
- case 'equals':
333
- return `Expr.dateIsEqual(${k}, '${dateFrom}')`;
334
- case 'lessThan':
335
- return `Expr.dateIsBefore(${k}, '${dateFrom}')`;
336
- case 'greaterThan':
337
- return `Expr.dateIsAfter(${k}, '${dateFrom}')`;
338
- case 'inRange':
339
- return `Expr.dateIsAfter(${k}, '${dateFrom}') && Expr.dateIsBefore(${k}, '${dateTo}')`;
340
- case 'isToday': {
341
- const now = new Date();
342
- const year = now.getFullYear();
343
- const month = (now.getMonth() + 1).toString().padStart(2, '0');
344
- const day = now.getDate().toString().padStart(2, '0');
345
- return `Expr.dateIsEqual(${k}, '${year}-${month}-${day} 00:00:00')`;
346
- }
347
- case 'blank':
348
- return `${k} == null`;
349
- case 'notBlank':
350
- return `${k} != null`;
351
- default:
352
- return null;
353
- }
255
+ return convertDateFilterToCriteria(model, k);
354
256
  }
355
257
  getFiltersByType(filterType) {
356
258
  var _a;
@@ -4,14 +4,14 @@ import { avoidTreeShaking, LifecycleMixin, respondToVisibility, } from '@genesis
4
4
  import { baseLayerLuminance, StandardLuminance } from '@microsoft/fast-components';
5
5
  import { attr, DOM, observable } from '@microsoft/fast-element';
6
6
  import { FoundationElement } from '@microsoft/fast-foundation';
7
- import { CellStyleModule, CheckboxEditorModule, ClientSideRowModelApiModule, ClientSideRowModelModule, ColumnApiModule, ColumnAutoSizeModule, createGrid, CsvExportModule, CustomEditorModule, DateEditorModule, DateFilterModule, EventApiModule, HighlightChangesModule, ModuleRegistry, NumberEditorModule, NumberFilterModule, PaginationModule, RenderApiModule, RowApiModule, RowDragModule, RowSelectionModule, RowStyleModule, SelectEditorModule, TextEditorModule, TextFilterModule, TooltipModule, } from 'ag-grid-community';
7
+ import { CellStyleModule, CheckboxEditorModule, ClientSideRowModelApiModule, ClientSideRowModelModule, ColumnApiModule, ColumnAutoSizeModule, createGrid, CsvExportModule, CustomEditorModule, DateEditorModule, DateFilterModule, EventApiModule, HighlightChangesModule, InfiniteRowModelModule, ModuleRegistry, NumberEditorModule, NumberFilterModule, PaginationModule, RenderApiModule, RowApiModule, RowDragModule, RowSelectionModule, RowStyleModule, SelectEditorModule, TextEditorModule, TextFilterModule, TooltipModule, } from 'ag-grid-community';
8
8
  import * as changeCase from 'change-case';
9
9
  import debounce from 'lodash.debounce';
10
10
  import { GridProCell } from './cell';
11
11
  import { DateEditor, MultiselectEditor, NumberEditor, SelectEditor, StringEditor, } from './cell-editors';
12
12
  import { ActionRenderer, ActionsMenuRenderer, BooleanRenderer, EditableRenderer, IconRenderer, SelectRenderer, StatusPillRenderer, } from './cell-renderers';
13
13
  import { GridProColumn, resolveVisibleColumnFields } from './column';
14
- import { GridProClientSideDatasource, GridProServerSideDatasource } from './datasource';
14
+ import { GridProClientSideDatasource, GridProInfiniteDatasource, GridProServerSideDatasource, } from './datasource';
15
15
  import { baseDatasourceEventNames } from './datasource/base.types';
16
16
  import { GridProGenesisDatasource, gridProGenesisDatasourceEventNames, } from './grid-pro-genesis-datasource';
17
17
  import { datasourceEventNames, } from './grid-pro-genesis-datasource/datasource-events.types';
@@ -21,7 +21,7 @@ import { StatePersistence } from './state-persistence';
21
21
  import { LabelValueStatusBarComponent, LoadMoreStatusBarComponent, ReloadStatusBarComponent, RowCountStatusBarComponent, } from './status-bar-components';
22
22
  import { ErrorTooltip } from './tooltips';
23
23
  import { convertToKebabCase, logger, mergeAndDedupColDefWithColumnState, sanitizeColumnState, } from './utils';
24
- avoidTreeShaking(GridProGenesisDatasource, GridProClientSideDatasource, GridProServerSideDatasource, GridProCell, GridProColumn);
24
+ avoidTreeShaking(GridProGenesisDatasource, GridProClientSideDatasource, GridProServerSideDatasource, GridProInfiniteDatasource, GridProCell, GridProColumn);
25
25
  ModuleRegistry.registerModules([
26
26
  CsvExportModule,
27
27
  ClientSideRowModelModule,
@@ -47,6 +47,7 @@ ModuleRegistry.registerModules([
47
47
  DateEditorModule,
48
48
  SelectEditorModule,
49
49
  CheckboxEditorModule,
50
+ InfiniteRowModelModule,
50
51
  // ValidationModule,
51
52
  ]);
52
53
  const DEBOUNCE_TIME = 400;
@@ -171,12 +172,6 @@ export class GridProBeta extends LifecycleMixin(FoundationElement) {
171
172
  this.withStatusBar = false;
172
173
  this.applyingDatasourceGridOptions = false;
173
174
  this.rehydrationAttempted = false;
174
- /**
175
- * Whether `onGridReady` has ever fired `datasourceEventNames.ready` at least once. A datasource
176
- * that connects (or restarts) after that point would otherwise miss the one-shot event entirely
177
- * — see `handleInitialize`, which replays it directly to any datasource that inits late.
178
- */
179
- this.hasEmittedDatasourceReady = false;
180
175
  this.rootEventsListeners = [];
181
176
  this.datasourceEventHandlers = [];
182
177
  this.gridEventsQueue = [];
@@ -247,6 +242,15 @@ export class GridProBeta extends LifecycleMixin(FoundationElement) {
247
242
  datasourceEventNames.applyServerSideTransaction,
248
243
  this.handleApplyServerSideTransaction.bind(this),
249
244
  ],
245
+ // Infinite Row Model specific events
246
+ [
247
+ datasourceEventNames.setInfiniteDatasource,
248
+ this.handleSetInfiniteDatasource.bind(this),
249
+ ],
250
+ [
251
+ datasourceEventNames.refreshInfiniteCache,
252
+ this.handleRefreshInfiniteCache.bind(this),
253
+ ],
250
254
  ];
251
255
  }
252
256
  /**
@@ -427,17 +431,6 @@ export class GridProBeta extends LifecycleMixin(FoundationElement) {
427
431
  */
428
432
  handleInitialize(event) {
429
433
  const { options, keepColDefsOnClearRowData } = event.detail;
430
- if (this.hasEmittedDatasourceReady) {
431
- // The grid already fired its one-shot ready event before this datasource registered its
432
- // `once` listener (late connection, or a restart after an earlier ready). Replay it
433
- // directly at the datasource once its own init() has finished registering that listener —
434
- // a microtask guarantees that ordering without depending on rAF (DOM.queueUpdate can stall
435
- // for reasons unrelated to this handshake, e.g. a backgrounded tab).
436
- const datasource = event.target;
437
- if (datasource) {
438
- queueMicrotask(() => datasource.dispatchEvent(new Event(datasourceEventNames.ready)));
439
- }
440
- }
441
434
  if (keepColDefsOnClearRowData) {
442
435
  this.columnState = this.gridApi.getColumnState();
443
436
  }
@@ -518,6 +511,21 @@ export class GridProBeta extends LifecycleMixin(FoundationElement) {
518
511
  }
519
512
  });
520
513
  }
514
+ // Same for the set filter, which enum columns ask for: it is Enterprise, so it only works
515
+ // when the app registered SetFilterModule - otherwise AG raises error #200 and the column
516
+ // ends up with no working filter at all.
517
+ if (!this.gridApi.isModuleRegistered('SetFilterModule')) {
518
+ schema.forEach((colDef) => {
519
+ if (colDef.filter === 'agSetColumnFilter') {
520
+ logger.warn('SetFilterModule is not registered, falling back to text filter');
521
+ colDef.filter = 'agTextColumnFilter';
522
+ // The set filter's value list means nothing to the text filter.
523
+ if (colDef.filterParams) {
524
+ delete colDef.filterParams.values;
525
+ }
526
+ }
527
+ });
528
+ }
521
529
  // Merge with template definitions
522
530
  const mergedColumnDefs = yield this.mergeAllColumnDefsAndStates(schema, true);
523
531
  this.gridApi.setGridOption('columnDefs', mergedColumnDefs);
@@ -680,6 +688,33 @@ export class GridProBeta extends LifecycleMixin(FoundationElement) {
680
688
  }
681
689
  }
682
690
  }
691
+ /**
692
+ * Handles setting infinite datasource
693
+ * @internal
694
+ */
695
+ handleSetInfiniteDatasource(event) {
696
+ const { datasource } = event.detail;
697
+ if (this.gridApi) {
698
+ this.gridApi.setGridOption('datasource', datasource);
699
+ }
700
+ }
701
+ /**
702
+ * Handles refreshing the infinite cache.
703
+ * @remarks Mirrors {@link GridProBeta.handleRefreshServerSide}: `purge` drops the block cache
704
+ * and re-reads, otherwise the loaded blocks are re-read in place.
705
+ * @internal
706
+ */
707
+ handleRefreshInfiniteCache(event) {
708
+ var _a;
709
+ if (!this.gridApi)
710
+ return;
711
+ if ((_a = event.detail) === null || _a === void 0 ? void 0 : _a.purge) {
712
+ this.gridApi.purgeInfiniteCache();
713
+ }
714
+ else {
715
+ this.gridApi.refreshInfiniteCache();
716
+ }
717
+ }
683
718
  combineAllGridComponents(gridOptionsComponents) {
684
719
  const defaultFoundationAgComponents = {
685
720
  [GridProRendererTypes.action]: ActionRenderer,
@@ -931,7 +966,14 @@ export class GridProBeta extends LifecycleMixin(FoundationElement) {
931
966
  get gridProDatasource() {
932
967
  return (this.querySelector('grid-pro-genesis-datasource') ||
933
968
  this.querySelector('grid-pro-client-side-datasource') ||
934
- this.querySelector('grid-pro-server-side-datasource'));
969
+ this.querySelector('grid-pro-server-side-datasource') ||
970
+ this.querySelector('grid-pro-infinite-datasource'));
971
+ }
972
+ /**
973
+ * @public
974
+ */
975
+ get isInfiniteRowModel() {
976
+ return this.gridProDatasource instanceof GridProInfiniteDatasource;
935
977
  }
936
978
  /**
937
979
  * Reports the currently visible columns to the datasource. The datasource decides what to do with
@@ -1027,7 +1069,6 @@ export class GridProBeta extends LifecycleMixin(FoundationElement) {
1027
1069
  // TODO: prevent rendering datasource slot until grid is ready
1028
1070
  // so there is no need for this even and handling it in datasources
1029
1071
  (_c = this.gridProDatasource) === null || _c === void 0 ? void 0 : _c.$emit(datasourceEventNames.ready);
1030
- this.hasEmittedDatasourceReady = true;
1031
1072
  this.restoreColumnState();
1032
1073
  this.restoreCachedFilterConfig();
1033
1074
  this.debouncedColumnAutosize();
@@ -1216,7 +1257,13 @@ export class GridProBeta extends LifecycleMixin(FoundationElement) {
1216
1257
  // The custom rowCount panel is used for server-side infinite scroll (load more) scenarios;
1217
1258
  // client-side row models use AG Grid's own row count component instead.
1218
1259
  if (this.statusBarConfig && this.statusBarConfig.rows === true) {
1219
- const isServerSide = this.isServerSide || (gridOptions === null || gridOptions === void 0 ? void 0 : gridOptions.rowModelType) === 'serverSide';
1260
+ // Check the derived gridOptions parameter, not this.gridOptions: setupStatusBar runs
1261
+ // before setLocalGridOptions populates the field, so on first init the field is still
1262
+ // undefined and a standalone grid's rowModelType would be missed.
1263
+ const isServerSide = this.isServerSide ||
1264
+ this.isInfiniteRowModel ||
1265
+ (gridOptions === null || gridOptions === void 0 ? void 0 : gridOptions.rowModelType) === 'infinite' ||
1266
+ (gridOptions === null || gridOptions === void 0 ? void 0 : gridOptions.rowModelType) === 'serverSide';
1220
1267
  if (isServerSide) {
1221
1268
  if (!this.panelExists(GridProStatusBarTypes.rowCount, statusPanels)) {
1222
1269
  statusPanels.push({
@@ -1263,7 +1310,9 @@ export class GridProBeta extends LifecycleMixin(FoundationElement) {
1263
1310
  }
1264
1311
  addDatasourcePanels(statusPanels) {
1265
1312
  if (this.gridProDatasource) {
1266
- const datasourceStatusPanels = this.gridProDatasource.getDatasourceStatusBarPanels(this.isServerSide, this.statusBarConfig);
1313
+ // The infinite row model loads on scroll, so its loadMore() is a no-op: suppress the
1314
+ // Load More panel for it the same way it is suppressed for the server-side row model.
1315
+ const datasourceStatusPanels = this.gridProDatasource.getDatasourceStatusBarPanels(this.isServerSide || this.isInfiniteRowModel, this.statusBarConfig);
1267
1316
  // Filter out duplicate datasource panels
1268
1317
  const newDatasourcePanels = datasourceStatusPanels.filter((panel) => !this.panelExists(panel.statusPanel, statusPanels));
1269
1318
  statusPanels.push(...newDatasourcePanels);
@@ -32,4 +32,7 @@ export const datasourceEventNames = {
32
32
  addGridCssClass: 'add-grid-css-class',
33
33
  removeGridCssClass: 'remove-grid-css-class',
34
34
  applyServerSideTransaction: 'apply-server-side-transaction',
35
+ // Infinite Row Model specific events
36
+ setInfiniteDatasource: 'set-infinite-datasource',
37
+ refreshInfiniteCache: 'refresh-infinite-cache',
35
38
  };
@@ -555,9 +555,6 @@ let GridProGenesisDatasource = class GridProGenesisDatasource extends LifecycleM
555
555
  this.criteriaFromFilters.delete(fieldName);
556
556
  this.update.next(this.criteriaFromFilters);
557
557
  }
558
- applyTransaction(transaction) {
559
- this.emitDataChanged(transaction);
560
- }
561
558
  handleSizeChanged(oldSize, newSize) {
562
559
  if (oldSize === newSize)
563
560
  return;
@@ -188,12 +188,6 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
188
188
  this.registeredGridEvents = new Set();
189
189
  this.gridEventListeners = new Map();
190
190
  this.boundGlobalEventListener = this.globalEventListener.bind(this);
191
- /**
192
- * Whether `onGridReady` has ever fired `datasourceEventNames.ready` at least once. A datasource
193
- * that connects (or restarts) after that point would otherwise miss the one-shot event entirely
194
- * — see `handleInitialize`, which replays it directly to any datasource that inits late.
195
- */
196
- this.hasEmittedDatasourceReady = false;
197
191
  this._filterConfig = undefined;
198
192
  this.agAttributes = {};
199
193
  this.agPropertiesMap = AG_PROPERTIES.reduce((map, property) => {
@@ -212,7 +206,18 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
212
206
  [datasourceEventNames.cacheFilterConfig, this.cacheFilterConfig.bind(this)], [datasourceEventNames.refreshServerSide, this.handleRefreshServerSide.bind(this)], [datasourceEventNames.setServerSideDatasource, this.handleSetServerSideDatasource.bind(this)], [datasourceEventNames.addGridCssClass, this.handleAddGridCssClass.bind(this)], [datasourceEventNames.removeGridCssClass, this.handleRemoveGridCssClass.bind(this)], [
213
207
  datasourceEventNames.applyServerSideTransaction,
214
208
  this.handleApplyServerSideTransaction.bind(this),
215
- ]);
209
+ ],
210
+ // Infinite Row Model events: not supported by this legacy grid (it registers neither the
211
+ // module nor the handlers). Fail loudly rather than leaving a silently empty grid.
212
+ [datasourceEventNames.setInfiniteDatasource, this.refuseInfiniteDatasource.bind(this)]);
213
+ }
214
+ /**
215
+ * The Infinite Row Model is only wired into the beta grid, so an infinite datasource placed
216
+ * inside this element can never load data. Report it instead of ignoring the event.
217
+ * @internal
218
+ */
219
+ refuseInfiniteDatasource() {
220
+ logger.error('grid-pro does not support the Infinite Row Model; use the beta grid (GridProBeta) with grid-pro-infinite-datasource / datasource-type="infinite".');
216
221
  }
217
222
  /**
218
223
  * Adds an event listener to the grid element.
@@ -377,17 +382,6 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
377
382
  */
378
383
  handleInitialize(event) {
379
384
  const { options, keepColDefsOnClearRowData } = event.detail;
380
- if (this.hasEmittedDatasourceReady) {
381
- // The grid already fired its one-shot ready event before this datasource registered its
382
- // `once` listener (late connection, or a restart after an earlier ready). Replay it
383
- // directly at the datasource once its own init() has finished registering that listener —
384
- // a microtask guarantees that ordering without depending on rAF (DOM.queueUpdate can stall
385
- // for reasons unrelated to this handshake, e.g. a backgrounded tab).
386
- const datasource = event.target;
387
- if (datasource) {
388
- queueMicrotask(() => datasource.dispatchEvent(new Event(datasourceEventNames.ready)));
389
- }
390
- }
391
385
  let columnDefinitions;
392
386
  if (keepColDefsOnClearRowData) {
393
387
  columnDefinitions = this.gridApi.getColumnDefs();
@@ -1045,7 +1039,6 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
1045
1039
  // TODO: prevent rendering datasource slot until grid is ready
1046
1040
  // so there is no need for this even and handling it in datasources
1047
1041
  (_b = this.gridProDatasource) === null || _b === void 0 ? void 0 : _b.$emit(datasourceEventNames.ready);
1048
- this.hasEmittedDatasourceReady = true;
1049
1042
  this.restoreColumnState();
1050
1043
  this.restoreCachedFilterConfig();
1051
1044
  this.debouncedColumnAutosize();