@genesislcap/grid-pro 15.20.2 → 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 +2161 -163
  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 -2
  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 -0
  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 -6
  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 -1
  43. package/dist/grid-pro.api.json +1355 -477
  44. package/dist/grid-pro.d.ts +962 -165
  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;
@@ -241,6 +242,15 @@ export class GridProBeta extends LifecycleMixin(FoundationElement) {
241
242
  datasourceEventNames.applyServerSideTransaction,
242
243
  this.handleApplyServerSideTransaction.bind(this),
243
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
+ ],
244
254
  ];
245
255
  }
246
256
  /**
@@ -501,6 +511,21 @@ export class GridProBeta extends LifecycleMixin(FoundationElement) {
501
511
  }
502
512
  });
503
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
+ }
504
529
  // Merge with template definitions
505
530
  const mergedColumnDefs = yield this.mergeAllColumnDefsAndStates(schema, true);
506
531
  this.gridApi.setGridOption('columnDefs', mergedColumnDefs);
@@ -663,6 +688,33 @@ export class GridProBeta extends LifecycleMixin(FoundationElement) {
663
688
  }
664
689
  }
665
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
+ }
666
718
  combineAllGridComponents(gridOptionsComponents) {
667
719
  const defaultFoundationAgComponents = {
668
720
  [GridProRendererTypes.action]: ActionRenderer,
@@ -914,7 +966,14 @@ export class GridProBeta extends LifecycleMixin(FoundationElement) {
914
966
  get gridProDatasource() {
915
967
  return (this.querySelector('grid-pro-genesis-datasource') ||
916
968
  this.querySelector('grid-pro-client-side-datasource') ||
917
- 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;
918
977
  }
919
978
  /**
920
979
  * Reports the currently visible columns to the datasource. The datasource decides what to do with
@@ -1198,7 +1257,13 @@ export class GridProBeta extends LifecycleMixin(FoundationElement) {
1198
1257
  // The custom rowCount panel is used for server-side infinite scroll (load more) scenarios;
1199
1258
  // client-side row models use AG Grid's own row count component instead.
1200
1259
  if (this.statusBarConfig && this.statusBarConfig.rows === true) {
1201
- 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';
1202
1267
  if (isServerSide) {
1203
1268
  if (!this.panelExists(GridProStatusBarTypes.rowCount, statusPanels)) {
1204
1269
  statusPanels.push({
@@ -1245,7 +1310,9 @@ export class GridProBeta extends LifecycleMixin(FoundationElement) {
1245
1310
  }
1246
1311
  addDatasourcePanels(statusPanels) {
1247
1312
  if (this.gridProDatasource) {
1248
- 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);
1249
1316
  // Filter out duplicate datasource panels
1250
1317
  const newDatasourcePanels = datasourceStatusPanels.filter((panel) => !this.panelExists(panel.statusPanel, statusPanels));
1251
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;
@@ -206,7 +206,18 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
206
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)], [
207
207
  datasourceEventNames.applyServerSideTransaction,
208
208
  this.handleApplyServerSideTransaction.bind(this),
209
- ]);
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".');
210
221
  }
211
222
  /**
212
223
  * Adds an event listener to the grid element.