@deephaven/iris-grid 1.28.1 → 1.29.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 (56) hide show
  1. package/dist/ColumnStatistics.js +1 -1
  2. package/dist/ColumnStatistics.js.map +1 -1
  3. package/dist/IrisGrid.d.ts +28 -4
  4. package/dist/IrisGrid.d.ts.map +1 -1
  5. package/dist/IrisGrid.js +185 -113
  6. package/dist/IrisGrid.js.map +1 -1
  7. package/dist/IrisGridCopyHandler.d.ts +5 -4
  8. package/dist/IrisGridCopyHandler.d.ts.map +1 -1
  9. package/dist/IrisGridCopyHandler.js +36 -29
  10. package/dist/IrisGridCopyHandler.js.map +1 -1
  11. package/dist/IrisGridModel.d.ts +2 -2
  12. package/dist/IrisGridModel.d.ts.map +1 -1
  13. package/dist/IrisGridModel.js +2 -2
  14. package/dist/IrisGridModel.js.map +1 -1
  15. package/dist/IrisGridSelectionUtils.d.ts +26 -0
  16. package/dist/IrisGridSelectionUtils.d.ts.map +1 -0
  17. package/dist/IrisGridSelectionUtils.js +84 -0
  18. package/dist/IrisGridSelectionUtils.js.map +1 -0
  19. package/dist/IrisGridTableModel.d.ts +4 -4
  20. package/dist/IrisGridTableModel.d.ts.map +1 -1
  21. package/dist/IrisGridTableModel.js +8 -8
  22. package/dist/IrisGridTableModel.js.map +1 -1
  23. package/dist/IrisGridTableModelTemplate.d.ts +25 -3
  24. package/dist/IrisGridTableModelTemplate.d.ts.map +1 -1
  25. package/dist/IrisGridTableModelTemplate.js +283 -79
  26. package/dist/IrisGridTableModelTemplate.js.map +1 -1
  27. package/dist/IrisGridTreeTableModel.d.ts +2 -0
  28. package/dist/IrisGridTreeTableModel.d.ts.map +1 -1
  29. package/dist/IrisGridTreeTableModel.js +11 -0
  30. package/dist/IrisGridTreeTableModel.js.map +1 -1
  31. package/dist/KeyedGridModel.d.ts +63 -0
  32. package/dist/KeyedGridModel.d.ts.map +1 -0
  33. package/dist/KeyedGridModel.js +12 -0
  34. package/dist/KeyedGridModel.js.map +1 -0
  35. package/dist/KeyedSelection.d.ts +194 -0
  36. package/dist/KeyedSelection.d.ts.map +1 -0
  37. package/dist/KeyedSelection.js +699 -0
  38. package/dist/KeyedSelection.js.map +1 -0
  39. package/dist/LazyIrisGrid.d.ts +1 -0
  40. package/dist/LazyIrisGrid.d.ts.map +1 -1
  41. package/dist/index.d.ts +3 -0
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +2 -0
  44. package/dist/index.js.map +1 -1
  45. package/dist/key-handlers/CopyKeyHandler.d.ts.map +1 -1
  46. package/dist/key-handlers/CopyKeyHandler.js +8 -6
  47. package/dist/key-handlers/CopyKeyHandler.js.map +1 -1
  48. package/dist/mousehandlers/IrisGridContextMenuHandler.d.ts +1 -1
  49. package/dist/mousehandlers/IrisGridContextMenuHandler.d.ts.map +1 -1
  50. package/dist/mousehandlers/IrisGridContextMenuHandler.js +94 -69
  51. package/dist/mousehandlers/IrisGridContextMenuHandler.js.map +1 -1
  52. package/dist/sidebar/TableCsvExporter.d.ts +7 -4
  53. package/dist/sidebar/TableCsvExporter.d.ts.map +1 -1
  54. package/dist/sidebar/TableCsvExporter.js +86 -38
  55. package/dist/sidebar/TableCsvExporter.js.map +1 -1
  56. package/package.json +9 -9
package/dist/IrisGrid.js CHANGED
@@ -19,7 +19,7 @@ import deepEqual from 'fast-deep-equal';
19
19
  import Log from '@deephaven/log';
20
20
  import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
21
21
  import { ContextActions, Stack, Menu, Page, Popper, ThemeExport, Tooltip, Button, ContextActionUtils, SlideTransition } from '@deephaven/components';
22
- import { Grid, GridRange, GridUtils, isEditableGridModel, isExpandableGridModel, isDeletableGridModel, isExpandableColumnGridModel } from '@deephaven/grid';
22
+ import { Grid, GridRange, GridUtils, isEditableGridModel, isExpandableGridModel, isDeletableGridModel, isExpandableColumnGridModel, RangedSelection } from '@deephaven/grid';
23
23
  import { dhEye, dhFilterFilled, dhGraphLineUp, dhTriangleDownSquare, vsClose, vsCloudDownload, vsEdit, vsFilter, vsMenu, vsReply, vsRuby, vsSearch, vsSplitHorizontal, vsSymbolOperator, vsTools } from '@deephaven/icons';
24
24
  import { DateUtils, Formatter, FormatterUtils, TableUtils, isSortDirection } from '@deephaven/jsapi-utils';
25
25
  import { assertNotNull, copyToClipboard, EMPTY_ARRAY, EMPTY_MAP, Pending, PromiseUtils, ValidationError, getOrThrow } from '@deephaven/utils';
@@ -44,6 +44,8 @@ import AdvancedFilterCreator from "./AdvancedFilterCreator.js";
44
44
  import { Aggregations, AggregationEdit, AggregationUtils, ChartBuilder, CustomColumnBuilder, OptionType, RollupRows, TableCsvExporter, TableSaver, VisibilityOrderingBuilder, DownloadServiceWorkerUtils } from "./sidebar/index.js";
45
45
  import { DEFAULT_REGISTRY, IrisGridContext } from "./IrisGridContextProvider.js";
46
46
  import IrisGridModel from "./IrisGridModel.js";
47
+ import { isKeyedGridModel } from "./KeyedGridModel.js";
48
+ import { KeyedSelection } from "./KeyedSelection.js";
47
49
  import IrisGridUtils from "./IrisGridUtils.js";
48
50
  import CrossColumnSearch from "./CrossColumnSearch.js";
49
51
  import { isPartitionedGridModel } from "./PartitionedGridModel.js";
@@ -135,6 +137,13 @@ class IrisGrid extends Component {
135
137
  _defineProperty(this, "getAdvancedMenuToggleMaximizeHandler", memoize(column => this.handleAdvancedFilterToggleMaximize.bind(this, column), {
136
138
  max: 100
137
139
  }));
140
+ /**
141
+ * For keyed models, return a function that creates an empty keyed selection.
142
+ * For non-keyed models, return `undefined` to use the Grid default.
143
+ */
144
+ _defineProperty(this, "getCachedCreateEmptySelection", memoize(isKeyed => isKeyed ? getModel => KeyedSelection.empty(getModel) : undefined, {
145
+ max: 1
146
+ }));
138
147
  _defineProperty(this, "getCachedAdvancedFilterMenuActions", memoize((model, column, advancedFilterOptions, sortDirection, formatter, isMaximized, onToggleMaximize) => /*#__PURE__*/_jsx(AdvancedFilterCreator, {
139
148
  model: model,
140
149
  column: column,
@@ -418,7 +427,7 @@ class IrisGrid extends Component {
418
427
  _defineProperty(this, "getCachedRenderer", memoize(rendererProp => rendererProp !== null && rendererProp !== void 0 ? rendererProp : new IrisGridRenderer(), {
419
428
  max: 1
420
429
  }));
421
- _defineProperty(this, "getAlwaysFetchColumns", memoize((alwaysFetchColumns, columns, movedColumns, floatingLeftColumnCount, floatingRightColumnCount, draggingRange) => {
430
+ _defineProperty(this, "getAlwaysFetchColumns", memoize((alwaysFetchColumns, columns, movedColumns, floatingLeftColumnCount, floatingRightColumnCount, model, draggingRange) => {
422
431
  var floatingColumns = [];
423
432
  for (var i = 0; i < floatingLeftColumnCount; i += 1) {
424
433
  floatingColumns.push(columns[GridUtils.getModelIndex(i, movedColumns)].name);
@@ -431,7 +440,12 @@ class IrisGrid extends Component {
431
440
  floatingColumns.push(columns[GridUtils.getModelIndex(_i2, movedColumns)].name);
432
441
  }
433
442
  }
434
- var columnSet = new Set([...alwaysFetchColumns, ...floatingColumns]);
443
+ var keyColumnIndices = isKeyedGridModel(model) ? model.selectionKeyColumnIndices : EMPTY_ARRAY;
444
+ var keyColumns = keyColumnIndices.map(i => {
445
+ var _columns$i;
446
+ return (_columns$i = columns[i]) === null || _columns$i === void 0 ? void 0 : _columns$i.name;
447
+ }).filter(n => n != null);
448
+ var columnSet = new Set([...alwaysFetchColumns, ...floatingColumns, ...keyColumns]);
435
449
  return Object.freeze([...columnSet]);
436
450
  }, {
437
451
  max: 1
@@ -601,6 +615,7 @@ class IrisGrid extends Component {
601
615
  this.handlePending = this.handlePending.bind(this);
602
616
  this.handlePendingCleared = this.handlePendingCleared.bind(this);
603
617
  this.handleSelectionChanged = this.handleSelectionChanged.bind(this);
618
+ this.handleGridSelectionChange = this.handleGridSelectionChange.bind(this);
604
619
  this.handleMovedColumnsChanged = this.handleMovedColumnsChanged.bind(this);
605
620
  this.handleHeaderGroupsChanged = this.handleHeaderGroupsChanged.bind(this);
606
621
  this.handleUpdate = this.handleUpdate.bind(this);
@@ -768,8 +783,7 @@ class IrisGrid extends Component {
768
783
  reverse: false,
769
784
  customColumns: [],
770
785
  selectDistinctColumns,
771
- // selected range in table
772
- selectedRanges: [],
786
+ gridSelection: null,
773
787
  // Current ongoing copy operation
774
788
  copyOperation: null,
775
789
  // The filter that is currently being applied. Reset after update is received
@@ -1595,16 +1609,27 @@ class IrisGrid extends Component {
1595
1609
  var includeHeaders = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1596
1610
  var formatValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
1597
1611
  var error = arguments.length > 3 ? arguments[3] : undefined;
1598
- var _this$props5 = this.props,
1599
- model = _this$props5.model,
1600
- canCopy = _this$props5.canCopy;
1612
+ var model = this.props.model;
1613
+ var bounded = GridRange.boundedRanges(ranges, model.columnCount, model.rowCount);
1614
+ var selection = new RangedSelection(bounded, () => model);
1615
+ this.copySelection(selection, includeHeaders, formatValues, error);
1616
+ }
1617
+ copySelection(selection) {
1618
+ var includeHeaders = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1619
+ var formatValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
1620
+ var error = arguments.length > 3 ? arguments[3] : undefined;
1621
+ var canCopy = this.props.canCopy;
1601
1622
  var _this$state6 = this.state,
1602
1623
  metricCalculator = _this$state6.metricCalculator,
1603
1624
  movedColumns = _this$state6.movedColumns;
1604
1625
  var userColumnWidths = metricCalculator.getUserColumnWidths();
1605
1626
  if (canCopy) {
1627
+ // Skip copy while keyed selection is still resolving — selectedKeyValues is empty.
1628
+ if (selection instanceof KeyedSelection && selection.pendingRanges.length > 0) {
1629
+ return;
1630
+ }
1606
1631
  var copyOperation = {
1607
- ranges: GridRange.boundedRanges(ranges, model.columnCount, model.rowCount),
1632
+ selection,
1608
1633
  includeHeaders,
1609
1634
  formatValues,
1610
1635
  movedColumns,
@@ -1615,7 +1640,7 @@ class IrisGrid extends Component {
1615
1640
  copyOperation
1616
1641
  });
1617
1642
  } else {
1618
- log.error('Attempted copyRanges for user without copy permission.');
1643
+ log.error('Attempted copySelection for user without copy permission.');
1619
1644
  }
1620
1645
  }
1621
1646
  startLoading(loadingText) {
@@ -2010,9 +2035,9 @@ class IrisGrid extends Component {
2010
2035
  (_this$grid0 = this.grid) === null || _this$grid0 === void 0 || _this$grid0.forceUpdate();
2011
2036
  }
2012
2037
  requestSortsChange(sorts) {
2013
- var _this$props6 = this.props,
2014
- isSortsControlled = _this$props6.isSortsControlled,
2015
- onSortsChange = _this$props6.onSortsChange;
2038
+ var _this$props5 = this.props,
2039
+ isSortsControlled = _this$props5.isSortsControlled,
2040
+ onSortsChange = _this$props5.onSortsChange;
2016
2041
  onSortsChange === null || onSortsChange === void 0 || onSortsChange(sorts);
2017
2042
  if (!isSortsControlled) {
2018
2043
  this.updateSorts(sorts);
@@ -2037,9 +2062,9 @@ class IrisGrid extends Component {
2037
2062
  (_this$grid1 = this.grid) === null || _this$grid1 === void 0 || _this$grid1.forceUpdate();
2038
2063
  }
2039
2064
  requestQuickFiltersChange(quickFilters) {
2040
- var _this$props7 = this.props,
2041
- isQuickFiltersControlled = _this$props7.isQuickFiltersControlled,
2042
- onQuickFiltersChange = _this$props7.onQuickFiltersChange;
2065
+ var _this$props6 = this.props,
2066
+ isQuickFiltersControlled = _this$props6.isQuickFiltersControlled,
2067
+ onQuickFiltersChange = _this$props6.onQuickFiltersChange;
2043
2068
  onQuickFiltersChange === null || onQuickFiltersChange === void 0 || onQuickFiltersChange(quickFilters);
2044
2069
  if (!isQuickFiltersControlled) {
2045
2070
  this.updateQuickFilters(quickFilters);
@@ -2099,9 +2124,9 @@ class IrisGrid extends Component {
2099
2124
  }
2100
2125
  isTableSearchAvailable() {
2101
2126
  var _model$layoutHints3, _dh$SearchDisplayMode, _dh$SearchDisplayMode2;
2102
- var _this$props8 = this.props,
2103
- model = _this$props8.model,
2104
- canToggleSearch = _this$props8.canToggleSearch;
2127
+ var _this$props7 = this.props,
2128
+ model = _this$props7.model,
2129
+ canToggleSearch = _this$props7.canToggleSearch;
2105
2130
  var dh = model.dh;
2106
2131
  var searchDisplayMode = model === null || model === void 0 || (_model$layoutHints3 = model.layoutHints) === null || _model$layoutHints3 === void 0 ? void 0 : _model$layoutHints3.searchDisplayMode;
2107
2132
  if (searchDisplayMode === ((_dh$SearchDisplayMode = dh.SearchDisplayMode) === null || _dh$SearchDisplayMode === void 0 ? void 0 : _dh$SearchDisplayMode.SEARCH_DISPLAY_HIDE)) {
@@ -2152,8 +2177,8 @@ class IrisGrid extends Component {
2152
2177
  (_this$gotoRowRef$curr = this.gotoRowRef.current) === null || _this$gotoRowRef$curr === void 0 || _this$gotoRowRef$curr.focus();
2153
2178
  return;
2154
2179
  }
2155
- var cursorRow = (_this$grid13 = this.grid) === null || _this$grid13 === void 0 ? void 0 : _this$grid13.state.cursorRow;
2156
- var cursorColumn = (_this$grid14 = this.grid) === null || _this$grid14 === void 0 ? void 0 : _this$grid14.state.cursorColumn;
2180
+ var cursorRow = (_this$grid13 = this.grid) === null || _this$grid13 === void 0 ? void 0 : _this$grid13.state.selection.cursorRow;
2181
+ var cursorColumn = (_this$grid14 = this.grid) === null || _this$grid14 === void 0 ? void 0 : _this$grid14.state.selection.cursorColumn;
2157
2182
  if (cursorRow == null || cursorColumn == null) {
2158
2183
  // if a cell is not selected / grid is not rendered
2159
2184
  this.setState({
@@ -2375,9 +2400,9 @@ class IrisGrid extends Component {
2375
2400
  // TODO: IDS-4242 Update Chart Preview
2376
2401
  }
2377
2402
  handleChartCreate(settings) {
2378
- var _this$props9 = this.props,
2379
- model = _this$props9.model,
2380
- onCreateChart = _this$props9.onCreateChart;
2403
+ var _this$props8 = this.props,
2404
+ model = _this$props8.model,
2405
+ onCreateChart = _this$props8.onCreateChart;
2381
2406
  onCreateChart(settings, model);
2382
2407
  }
2383
2408
  handleGridError(error) {
@@ -2620,17 +2645,26 @@ class IrisGrid extends Component {
2620
2645
  * reconciles against the grid's current `movedColumns` at draw time.
2621
2646
  */
2622
2647
  handleSchemaChanged() {
2648
+ var _this$grid18;
2623
2649
  var model = this.props.model;
2624
2650
  this.setState({
2625
2651
  movedColumns: model.initialMovedColumns
2626
2652
  });
2653
+
2654
+ // Clear the selection if the model type changed (keyed vs non-keyed)
2655
+ var currentSelection = (_this$grid18 = this.grid) === null || _this$grid18 === void 0 ? void 0 : _this$grid18.state.selection;
2656
+ if (currentSelection == null) return;
2657
+ var modelIsKeyed = isKeyedGridModel(model);
2658
+ var selectionIsKeyed = currentSelection instanceof KeyedSelection;
2659
+ if (modelIsKeyed !== selectionIsKeyed) {
2660
+ var _this$grid19;
2661
+ (_this$grid19 = this.grid) === null || _this$grid19 === void 0 || _this$grid19.clearSelectedRanges();
2662
+ }
2627
2663
  }
2628
2664
  handleViewChanged(metrics) {
2629
- var _this$grid$state, _this$grid18;
2665
+ var _this$grid$state$sele, _this$grid20;
2630
2666
  var model = this.props.model;
2631
- var _ref19 = (_this$grid$state = (_this$grid18 = this.grid) === null || _this$grid18 === void 0 ? void 0 : _this$grid18.state) !== null && _this$grid$state !== void 0 ? _this$grid$state : {},
2632
- _ref19$selectionEndRo = _ref19.selectionEndRow,
2633
- selectionEndRow = _ref19$selectionEndRo === void 0 ? 0 : _ref19$selectionEndRo;
2667
+ var selectionEndRow = (_this$grid$state$sele = (_this$grid20 = this.grid) === null || _this$grid20 === void 0 ? void 0 : _this$grid20.state.selection.selectionEndRow) !== null && _this$grid$state$sele !== void 0 ? _this$grid$state$sele : 0;
2634
2668
  var pendingRowCount = 0;
2635
2669
  if (isEditableGridModel(model) && model.isEditable) {
2636
2670
  assertNotNull(metrics);
@@ -2655,29 +2689,64 @@ class IrisGrid extends Component {
2655
2689
  pendingRowCount
2656
2690
  });
2657
2691
  }
2692
+
2693
+ /** @deprecated Use `handleGridSelectionChange` instead. */
2658
2694
  handleSelectionChanged(selectedRanges) {
2659
2695
  assertNotNull(selectedRanges);
2660
2696
  var onSelectionChanged = this.props.onSelectionChanged;
2697
+ onSelectionChanged === null || onSelectionChanged === void 0 || onSelectionChanged(selectedRanges);
2698
+ }
2699
+ handleGridSelectionChange(selection) {
2700
+ var onSelectionChange = this.props.onSelectionChange;
2661
2701
  var copyOperation = this.state.copyOperation;
2662
2702
  this.setState({
2663
- selectedRanges
2703
+ gridSelection: selection
2664
2704
  });
2665
2705
  if (copyOperation != null) {
2666
2706
  this.setState({
2667
2707
  copyOperation: null
2668
2708
  });
2669
2709
  }
2670
-
2671
- // We get 2 identical ranges here,
2672
- // but consolidating in `Grid#moveSelection` causes
2673
- // deselection to break, so just consolidate here.
2674
- // This will only update the goto row input for row index
2675
- if (GridRange.rowCount(GridRange.consolidate(selectedRanges)) === 1 && selectedRanges[0].startRow != null) {
2710
+ var cursorRow = selection.cursorRow;
2711
+ if (cursorRow != null) {
2676
2712
  this.setState({
2677
- gotoRow: "".concat(selectedRanges[0].startRow + 1)
2713
+ gotoRow: "".concat(cursorRow + 1)
2678
2714
  });
2679
2715
  }
2680
- onSelectionChanged(selectedRanges);
2716
+ onSelectionChange === null || onSelectionChange === void 0 || onSelectionChange(selection);
2717
+ if (selection instanceof KeyedSelection && selection.pendingRanges.length > 0) {
2718
+ this.resolveKeyedSelection(selection);
2719
+ }
2720
+ }
2721
+
2722
+ /**
2723
+ * Resolves a KeyedSelection with ranges outside the current viewport by
2724
+ * fetching the missing key values from the server. Triggered by
2725
+ * `Grid.setSelectedRanges` (plugin-driven programmatic selection) and by
2726
+ * shift+click/drag that spans a scrolled-away region.
2727
+ */
2728
+ resolveKeyedSelection(pending) {
2729
+ var _this6 = this;
2730
+ return _asyncToGenerator(function* () {
2731
+ var model = _this6.props.model;
2732
+ if (!isKeyedGridModel(model)) return;
2733
+ var pendingRanges = pending.pendingRanges;
2734
+ if (pendingRanges.length === 0) return;
2735
+ try {
2736
+ var _this6$grid;
2737
+ var keyValues = yield model.fetchKeyValuesForRowRanges(pendingRanges);
2738
+ // Bail if the user changed the selection while we were fetching.
2739
+ if (((_this6$grid = _this6.grid) === null || _this6$grid === void 0 ? void 0 : _this6$grid.getSelection()) !== pending) return;
2740
+ _this6.grid.setSelection(pending.resolve(keyValues));
2741
+ } catch (e) {
2742
+ var _this6$grid2;
2743
+ log.error('resolveKeyedSelection failed', e);
2744
+ // Prevent the unusable pending selection from remaining installed indefinitely.
2745
+ if (((_this6$grid2 = _this6.grid) === null || _this6$grid2 === void 0 ? void 0 : _this6$grid2.getSelection()) === pending) {
2746
+ _this6.grid.setSelection(pending.clear());
2747
+ }
2748
+ }
2749
+ })();
2681
2750
  }
2682
2751
  handleMovedColumnsChanged(movedColumns, onChangeApplied) {
2683
2752
  this.setState({
@@ -2695,8 +2764,8 @@ class IrisGrid extends Component {
2695
2764
  // Parsing them again causes a loop with undo/redo that makes it unusable
2696
2765
  columnHeaderGroups: columnHeaderGroups.every(group => isColumnHeaderGroup(group) && group.isValid()) ? columnHeaderGroups : IrisGridUtils.parseColumnHeaderGroups(model, columnHeaderGroups).groups
2697
2766
  }, () => {
2698
- var _this$grid19;
2699
- return (_this$grid19 = this.grid) === null || _this$grid19 === void 0 ? void 0 : _this$grid19.forceUpdate();
2767
+ var _this$grid21;
2768
+ return (_this$grid21 = this.grid) === null || _this$grid21 === void 0 ? void 0 : _this$grid21.forceUpdate();
2700
2769
  });
2701
2770
  }
2702
2771
  handleTooltipRef(tooltip) {
@@ -2885,7 +2954,7 @@ class IrisGrid extends Component {
2885
2954
  return this.discardPending();
2886
2955
  }
2887
2956
  handlePendingDataUpdated() {
2888
- var _this$grid20;
2957
+ var _this$grid22;
2889
2958
  log.debug('pending data updated');
2890
2959
  var model = this.props.model;
2891
2960
  var pendingDataMap = model.pendingDataMap,
@@ -2895,10 +2964,10 @@ class IrisGrid extends Component {
2895
2964
  pendingDataErrors,
2896
2965
  pendingSaveError: null
2897
2966
  });
2898
- (_this$grid20 = this.grid) === null || _this$grid20 === void 0 || _this$grid20.forceUpdate();
2967
+ (_this$grid22 = this.grid) === null || _this$grid22 === void 0 || _this$grid22.forceUpdate();
2899
2968
  }
2900
2969
  handleResizeColumn(modelIndex) {
2901
- var _this$grid21;
2970
+ var _this$grid23;
2902
2971
  var _this$state18 = this.state,
2903
2972
  metrics = _this$state18.metrics,
2904
2973
  metricCalculator = _this$state18.metricCalculator;
@@ -2911,23 +2980,23 @@ class IrisGrid extends Component {
2911
2980
  } else {
2912
2981
  metricCalculator.setColumnWidth(modelIndex, contentWidth);
2913
2982
  }
2914
- (_this$grid21 = this.grid) === null || _this$grid21 === void 0 || _this$grid21.forceUpdate();
2983
+ (_this$grid23 = this.grid) === null || _this$grid23 === void 0 || _this$grid23.forceUpdate();
2915
2984
  }
2916
2985
  handleResizeAllColumns() {
2917
- var _this$grid22;
2986
+ var _this$grid24;
2918
2987
  var _this$state19 = this.state,
2919
2988
  metrics = _this$state19.metrics,
2920
2989
  metricCalculator = _this$state19.metricCalculator;
2921
2990
  if (!metrics) throw new Error('Metrics not set');
2922
2991
  var allColumns = [...metrics.allColumnWidths.entries()];
2923
- var visibleColumns = allColumns.filter(_ref20 => {
2924
- var _ref21 = _slicedToArray(_ref20, 2),
2925
- _ = _ref21[0],
2926
- width = _ref21[1];
2992
+ var visibleColumns = allColumns.filter(_ref19 => {
2993
+ var _ref20 = _slicedToArray(_ref19, 2),
2994
+ _ = _ref20[0],
2995
+ width = _ref20[1];
2927
2996
  return width !== 0;
2928
- }).map(_ref22 => {
2929
- var _ref23 = _slicedToArray(_ref22, 1),
2930
- modelIndex = _ref23[0];
2997
+ }).map(_ref21 => {
2998
+ var _ref22 = _slicedToArray(_ref21, 1),
2999
+ modelIndex = _ref22[0];
2931
3000
  return modelIndex;
2932
3001
  });
2933
3002
  var contentWidths = metrics.contentColumnWidths;
@@ -2949,7 +3018,7 @@ class IrisGrid extends Component {
2949
3018
  metricCalculator.setColumnWidth(_modelIndex, _contentWidth);
2950
3019
  }
2951
3020
  }
2952
- (_this$grid22 = this.grid) === null || _this$grid22 === void 0 || _this$grid22.forceUpdate();
3021
+ (_this$grid24 = this.grid) === null || _this$grid24 === void 0 || _this$grid24.forceUpdate();
2953
3022
  }
2954
3023
 
2955
3024
  /**
@@ -2990,8 +3059,8 @@ class IrisGrid extends Component {
2990
3059
  if (shouldStartLoading) {
2991
3060
  this.startLoading("Aggregating ".concat(aggregation.operation, "..."));
2992
3061
  }
2993
- this.setState(_ref24 => {
2994
- var aggregationSettings = _ref24.aggregationSettings;
3062
+ this.setState(_ref23 => {
3063
+ var aggregationSettings = _ref23.aggregationSettings;
2995
3064
  return {
2996
3065
  selectedAggregation: aggregation,
2997
3066
  aggregationSettings: _objectSpread(_objectSpread({}, aggregationSettings), {}, {
@@ -3095,8 +3164,8 @@ class IrisGrid extends Component {
3095
3164
  */
3096
3165
  removeEmptyAggregations() {
3097
3166
  log.debug('removeEmptyAggregations');
3098
- this.setState(_ref25 => {
3099
- var aggregationSettings = _ref25.aggregationSettings;
3167
+ this.setState(_ref24 => {
3168
+ var aggregationSettings = _ref24.aggregationSettings;
3100
3169
  var aggregations = aggregationSettings.aggregations;
3101
3170
  var newAggregations = aggregations.filter(a => a.selected.length > 0 || a.invert);
3102
3171
  if (newAggregations.length !== aggregations.length) {
@@ -3115,14 +3184,14 @@ class IrisGrid extends Component {
3115
3184
  }
3116
3185
  seekRow(inputString) {
3117
3186
  var _arguments = arguments,
3118
- _this6 = this;
3187
+ _this7 = this;
3119
3188
  return _asyncToGenerator(function* () {
3120
- var _this6$grid;
3189
+ var _this7$grid;
3121
3190
  var isBackwards = _arguments.length > 1 && _arguments[1] !== undefined ? _arguments[1] : false;
3122
- var _this6$state = _this6.state,
3123
- selectedColumnName = _this6$state.gotoValueSelectedColumnName,
3124
- gotoValueSelectedFilter = _this6$state.gotoValueSelectedFilter;
3125
- var model = _this6.props.model;
3191
+ var _this7$state = _this7.state,
3192
+ selectedColumnName = _this7$state.gotoValueSelectedColumnName,
3193
+ gotoValueSelectedFilter = _this7$state.gotoValueSelectedFilter;
3194
+ var model = _this7.props.model;
3126
3195
  var dh = model.dh;
3127
3196
  if (!model.isSeekRowAvailable) {
3128
3197
  return;
@@ -3134,14 +3203,14 @@ class IrisGrid extends Component {
3134
3203
  if (selectedColumn === undefined) {
3135
3204
  return;
3136
3205
  }
3137
- var searchFromRow = (_this6$grid = _this6.grid) === null || _this6$grid === void 0 ? void 0 : _this6$grid.state.cursorRow;
3206
+ var searchFromRow = (_this7$grid = _this7.grid) === null || _this7$grid === void 0 ? void 0 : _this7$grid.state.selection.cursorRow;
3138
3207
  if (searchFromRow == null) {
3139
3208
  searchFromRow = 0;
3140
3209
  }
3141
3210
  var isContains = gotoValueSelectedFilter === FilterType.contains || gotoValueSelectedFilter === FilterType.containsIgnoreCase;
3142
3211
  var isIgnoreCase = gotoValueSelectedFilter === FilterType.eqIgnoreCase || gotoValueSelectedFilter === FilterType.containsIgnoreCase;
3143
3212
  try {
3144
- var _this6$grid2;
3213
+ var _this7$grid2;
3145
3214
  var formatter = model.formatter;
3146
3215
  var columnDataType = TableUtils.getNormalizedType(selectedColumn.type);
3147
3216
  var rowIndex;
@@ -3178,15 +3247,15 @@ class IrisGrid extends Component {
3178
3247
  }
3179
3248
  default:
3180
3249
  {
3181
- rowIndex = yield model.seekRow(searchFromRow, selectedColumn, dh.ValueType.STRING, _this6.tableUtils.makeValue(selectedColumn.type, inputString, formatter.timeZone), undefined, undefined, isBackwards !== null && isBackwards !== void 0 ? isBackwards : false);
3250
+ rowIndex = yield model.seekRow(searchFromRow, selectedColumn, dh.ValueType.STRING, _this7.tableUtils.makeValue(selectedColumn.type, inputString, formatter.timeZone), undefined, undefined, isBackwards !== null && isBackwards !== void 0 ? isBackwards : false);
3182
3251
  }
3183
3252
  }
3184
- (_this6$grid2 = _this6.grid) === null || _this6$grid2 === void 0 || _this6$grid2.setFocusRow(rowIndex);
3185
- _this6.setState({
3253
+ (_this7$grid2 = _this7.grid) === null || _this7$grid2 === void 0 || _this7$grid2.setFocusRow(rowIndex);
3254
+ _this7.setState({
3186
3255
  gotoValueError: ''
3187
3256
  });
3188
3257
  } catch (e) {
3189
- _this6.setState({
3258
+ _this7.setState({
3190
3259
  gotoValueError: 'invalid input'
3191
3260
  });
3192
3261
  }
@@ -3271,11 +3340,11 @@ class IrisGrid extends Component {
3271
3340
  onStateChange(irisGridState, gridState);
3272
3341
  }
3273
3342
  handleOverflowClose() {
3274
- var _this$grid23;
3343
+ var _this$grid25;
3275
3344
  this.setState({
3276
3345
  showOverflowModal: false
3277
3346
  });
3278
- (_this$grid23 = this.grid) === null || _this$grid23 === void 0 || _this$grid23.focus(); // Focus on the grid after closing the overflow modal
3347
+ (_this$grid25 = this.grid) === null || _this$grid25 === void 0 || _this$grid25.focus(); // Focus on the grid after closing the overflow modal
3279
3348
  }
3280
3349
  handleOpenNoPastePermissionModal(errorMessage) {
3281
3350
  this.setState({
@@ -3345,22 +3414,22 @@ class IrisGrid extends Component {
3345
3414
  gotoRowError: 'Invalid row index'
3346
3415
  });
3347
3416
  } else if (rowInt === 0) {
3348
- var _this$grid24;
3417
+ var _this$grid26;
3349
3418
  this.setState({
3350
3419
  gotoRowError: '',
3351
3420
  gotoValueError: ''
3352
3421
  });
3353
- (_this$grid24 = this.grid) === null || _this$grid24 === void 0 || _this$grid24.setFocusRow(0);
3422
+ (_this$grid26 = this.grid) === null || _this$grid26 === void 0 || _this$grid26.setFocusRow(0);
3354
3423
  } else if (rowInt < 0) {
3355
- var _this$grid25;
3424
+ var _this$grid27;
3356
3425
  this.setState({
3357
3426
  gotoRowError: '',
3358
3427
  gotoValueError: ''
3359
3428
  });
3360
- (_this$grid25 = this.grid) === null || _this$grid25 === void 0 || _this$grid25.setFocusRow(rowInt + rowCount);
3429
+ (_this$grid27 = this.grid) === null || _this$grid27 === void 0 || _this$grid27.setFocusRow(rowInt + rowCount);
3361
3430
  } else {
3362
- var _this$grid26;
3363
- (_this$grid26 = this.grid) === null || _this$grid26 === void 0 || _this$grid26.setFocusRow(rowInt - 1);
3431
+ var _this$grid28;
3432
+ (_this$grid28 = this.grid) === null || _this$grid28 === void 0 || _this$grid28.setFocusRow(rowInt - 1);
3364
3433
  this.setState({
3365
3434
  gotoRowError: '',
3366
3435
  gotoValueError: ''
@@ -3458,9 +3527,9 @@ class IrisGrid extends Component {
3458
3527
  });
3459
3528
  }
3460
3529
  handleGotoValueSelectedColumnNameChanged(columnName) {
3461
- var _this$grid27;
3530
+ var _this$grid29;
3462
3531
  var model = this.props.model;
3463
- var cursorRow = (_this$grid27 = this.grid) === null || _this$grid27 === void 0 ? void 0 : _this$grid27.state.cursorRow;
3532
+ var cursorRow = (_this$grid29 = this.grid) === null || _this$grid29 === void 0 ? void 0 : _this$grid29.state.selection.cursorRow;
3464
3533
  var _this$state21 = this.state,
3465
3534
  prevColumnName = _this$state21.gotoValueSelectedColumnName,
3466
3535
  gotoValueManuallyChanged = _this$state21.gotoValueManuallyChanged;
@@ -3516,7 +3585,7 @@ class IrisGrid extends Component {
3516
3585
  * @returns The filter input field element or null if not applicable
3517
3586
  */
3518
3587
  getFilterBarInput(metrics, metricCalculator, focusedFilterBarColumn, quickFilters, advancedFilters) {
3519
- var _this$grid28;
3588
+ var _this$grid30;
3520
3589
  if (metrics == null || focusedFilterBarColumn == null) {
3521
3590
  return null;
3522
3591
  }
@@ -3571,7 +3640,7 @@ class IrisGrid extends Component {
3571
3640
  onChange: this.handleFilterBarChange,
3572
3641
  onDone: this.handleFilterBarDone,
3573
3642
  onTab: this.handleFilterBarTab,
3574
- onContextMenu: (_this$grid28 = this.grid) === null || _this$grid28 === void 0 ? void 0 : _this$grid28.handleContextMenu,
3643
+ onContextMenu: (_this$grid30 = this.grid) === null || _this$grid30 === void 0 ? void 0 : _this$grid30.handleContextMenu,
3575
3644
  debounceMs: debounceMs,
3576
3645
  value: value
3577
3646
  }, focusedFilterBarColumn);
@@ -3579,25 +3648,25 @@ class IrisGrid extends Component {
3579
3648
  render() {
3580
3649
  var _rollupConfig$columns7,
3581
3650
  _rollupConfig$columns8,
3582
- _this7 = this,
3583
- _this$grid29,
3651
+ _this8 = this,
3652
+ _this$grid31,
3584
3653
  _openOptions;
3585
- var _this$props0 = this.props,
3586
- children = _this$props0.children,
3587
- customFilters = _this$props0.customFilters,
3588
- getDownloadWorker = _this$props0.getDownloadWorker,
3589
- isSelectingColumn = _this$props0.isSelectingColumn,
3590
- isStuckToBottom = _this$props0.isStuckToBottom,
3591
- isStuckToRight = _this$props0.isStuckToRight,
3592
- model = _this$props0.model,
3593
- name = _this$props0.name,
3594
- onlyFetchVisibleColumns = _this$props0.onlyFetchVisibleColumns,
3595
- alwaysFetchColumns = _this$props0.alwaysFetchColumns,
3596
- advancedSettings = _this$props0.advancedSettings,
3597
- onAdvancedSettingsChange = _this$props0.onAdvancedSettingsChange,
3598
- canDownloadCsv = _this$props0.canDownloadCsv,
3599
- onCreateChart = _this$props0.onCreateChart,
3600
- transformTableOptions = _this$props0.transformTableOptions;
3654
+ var _this$props9 = this.props,
3655
+ children = _this$props9.children,
3656
+ customFilters = _this$props9.customFilters,
3657
+ getDownloadWorker = _this$props9.getDownloadWorker,
3658
+ isSelectingColumn = _this$props9.isSelectingColumn,
3659
+ isStuckToBottom = _this$props9.isStuckToBottom,
3660
+ isStuckToRight = _this$props9.isStuckToRight,
3661
+ model = _this$props9.model,
3662
+ name = _this$props9.name,
3663
+ onlyFetchVisibleColumns = _this$props9.onlyFetchVisibleColumns,
3664
+ alwaysFetchColumns = _this$props9.alwaysFetchColumns,
3665
+ advancedSettings = _this$props9.advancedSettings,
3666
+ onAdvancedSettingsChange = _this$props9.onAdvancedSettingsChange,
3667
+ canDownloadCsv = _this$props9.canDownloadCsv,
3668
+ onCreateChart = _this$props9.onCreateChart,
3669
+ transformTableOptions = _this$props9.transformTableOptions;
3601
3670
  var cellInputRendererRegistry = this.context.cellInputRendererRegistry;
3602
3671
  var _this$state22 = this.state,
3603
3672
  metricCalculator = _this$state22.metricCalculator,
@@ -3633,7 +3702,7 @@ class IrisGrid extends Component {
3633
3702
  sorts = _this$state22.sorts,
3634
3703
  reverse = _this$state22.reverse,
3635
3704
  customColumns = _this$state22.customColumns,
3636
- selectedRanges = _this$state22.selectedRanges,
3705
+ gridSelection = _this$state22.gridSelection,
3637
3706
  isTableDownloading = _this$state22.isTableDownloading,
3638
3707
  tableDownloadStatus = _this$state22.tableDownloadStatus,
3639
3708
  tableDownloadProgress = _this$state22.tableDownloadProgress,
@@ -3733,7 +3802,7 @@ class IrisGrid extends Component {
3733
3802
  var visibleColumns = metrics.visibleColumns;
3734
3803
  var _loop2 = function _loop2() {
3735
3804
  var columnIndex = visibleColumns[i];
3736
- var modelColumn = _this7.getModelColumn(columnIndex);
3805
+ var modelColumn = _this8.getModelColumn(columnIndex);
3737
3806
  if (modelColumn != null) {
3738
3807
  var isFilterable = model.isFilterable(modelColumn);
3739
3808
  var buttonCoordinates = isFilterable && metricState ? metricCalculator.getAdvancedFilterButtonCoordinates(columnIndex, metricState, metrics) : null;
@@ -3759,22 +3828,22 @@ class IrisGrid extends Component {
3759
3828
  'filter-set': isFilterSet
3760
3829
  }),
3761
3830
  onClick: () => {
3762
- _this7.setState({
3831
+ _this8.setState({
3763
3832
  shownAdvancedFilter: columnIndex,
3764
3833
  maximizedAdvancedFilter: null
3765
3834
  });
3766
3835
  },
3767
3836
  onContextMenu: event => {
3768
- var _this7$grid;
3769
- (_this7$grid = _this7.grid) === null || _this7$grid === void 0 || _this7$grid.handleContextMenu(event);
3837
+ var _this8$grid;
3838
+ (_this8$grid = _this8.grid) === null || _this8$grid === void 0 || _this8$grid.handleContextMenu(event);
3770
3839
  },
3771
3840
  onMouseEnter: () => {
3772
- _this7.setState({
3841
+ _this8.setState({
3773
3842
  hoverAdvancedFilter: columnIndex
3774
3843
  });
3775
3844
  },
3776
3845
  onMouseLeave: () => {
3777
- _this7.setState({
3846
+ _this8.setState({
3778
3847
  hoverAdvancedFilter: null
3779
3848
  });
3780
3849
  },
@@ -3825,7 +3894,7 @@ class IrisGrid extends Component {
3825
3894
  width: columnWidth,
3826
3895
  height: columnHeaderHeight
3827
3896
  };
3828
- var modelColumn = _this7.getModelColumn(columnIndex);
3897
+ var modelColumn = _this8.getModelColumn(columnIndex);
3829
3898
  if (modelColumn != null) {
3830
3899
  var column = model.columns[modelColumn];
3831
3900
  if (column == null) {
@@ -3835,8 +3904,8 @@ class IrisGrid extends Component {
3835
3904
  return 1; // continue
3836
3905
  }
3837
3906
  var advancedFilter = advancedFilters.get(modelColumn);
3838
- var _ref26 = advancedFilter || {},
3839
- advancedFilterOptions = _ref26.options;
3907
+ var _ref25 = advancedFilter || {},
3908
+ advancedFilterOptions = _ref25.options;
3840
3909
  var sort = TableUtils.getSortForColumn(model.sort, column.name);
3841
3910
  var sortDirection = sort ? sort.direction : null;
3842
3911
  if (!isSortDirection(sortDirection)) {
@@ -3848,9 +3917,9 @@ class IrisGrid extends Component {
3848
3917
  children: /*#__PURE__*/_jsx(Popper, {
3849
3918
  className: "advanced-filter-menu-popper",
3850
3919
  isMaximized: shownAdvancedFilter === columnIndex && maximizedAdvancedFilter === columnIndex,
3851
- onEntered: _this7.getAdvancedMenuOpenedHandler(columnIndex),
3920
+ onEntered: _this8.getAdvancedMenuOpenedHandler(columnIndex),
3852
3921
  onExited: () => {
3853
- _this7.handleAdvancedMenuClosed(columnIndex);
3922
+ _this8.handleAdvancedMenuClosed(columnIndex);
3854
3923
  },
3855
3924
  isShown: shownAdvancedFilter === columnIndex,
3856
3925
  interactive: true,
@@ -3858,7 +3927,7 @@ class IrisGrid extends Component {
3858
3927
  options: {
3859
3928
  positionFixed: true
3860
3929
  },
3861
- children: _this7.getCachedAdvancedFilterMenuActions(model, column, advancedFilterOptions, sortDirection, formatter, shownAdvancedFilter === columnIndex && maximizedAdvancedFilter === columnIndex, _this7.getAdvancedMenuToggleMaximizeHandler(columnIndex))
3930
+ children: _this8.getCachedAdvancedFilterMenuActions(model, column, advancedFilterOptions, sortDirection, formatter, shownAdvancedFilter === columnIndex && maximizedAdvancedFilter === columnIndex, _this8.getAdvancedMenuToggleMaximizeHandler(columnIndex))
3862
3931
  })
3863
3932
  }, columnIndex);
3864
3933
  advancedFilterMenus.push(element);
@@ -3952,7 +4021,7 @@ class IrisGrid extends Component {
3952
4021
  onDownload: this.handleDownloadTable,
3953
4022
  onDownloadStart: this.handleDownloadTableStart,
3954
4023
  onCancel: this.handleCancelDownloadTable,
3955
- selectedRanges: selectedRanges
4024
+ selection: gridSelection
3956
4025
  }, OptionType.TABLE_EXPORTER);
3957
4026
  case OptionType.SELECT_DISTINCT:
3958
4027
  return /*#__PURE__*/_jsx(SelectDistinctBuilder, {
@@ -4043,6 +4112,7 @@ class IrisGrid extends Component {
4043
4112
  this.grid = grid;
4044
4113
  },
4045
4114
  isStickyBottom: !isEditableGridModel(model) || !model.isEditable,
4115
+ createEmptySelection: this.getCachedCreateEmptySelection(isKeyedGridModel(model)),
4046
4116
  isStuckToBottom: isStuckToBottom,
4047
4117
  isStuckToRight: isStuckToRight,
4048
4118
  metricCalculator: metricCalculator,
@@ -4054,6 +4124,7 @@ class IrisGrid extends Component {
4054
4124
  onError: this.handleGridError,
4055
4125
  onViewChanged: this.handleViewChanged,
4056
4126
  onSelectionChanged: this.handleSelectionChanged,
4127
+ onSelectionChange: this.handleGridSelectionChange,
4057
4128
  onMovedColumnsChanged: this.handleMovedColumnsChanged,
4058
4129
  renderer: this.renderer,
4059
4130
  cellInputRendererRegistry: cellInputRendererRegistry !== null && cellInputRendererRegistry !== void 0 ? cellInputRendererRegistry : DEFAULT_REGISTRY,
@@ -4077,7 +4148,7 @@ class IrisGrid extends Component {
4077
4148
  movedColumns: movedColumns,
4078
4149
  customColumns: customColumns,
4079
4150
  hiddenColumns: hiddenColumns,
4080
- alwaysFetchColumns: this.getAlwaysFetchColumns(alwaysFetchColumns, model.columns, movedColumns, model.floatingLeftColumnCount, model.floatingRightColumnCount, (_this$grid29 = this.grid) === null || _this$grid29 === void 0 || (_this$grid29 = _this$grid29.state.draggingColumn) === null || _this$grid29 === void 0 ? void 0 : _this$grid29.range),
4151
+ alwaysFetchColumns: this.getAlwaysFetchColumns(alwaysFetchColumns, model.columns, movedColumns, model.floatingLeftColumnCount, model.floatingRightColumnCount, model, (_this$grid31 = this.grid) === null || _this$grid31 === void 0 || (_this$grid31 = _this$grid31.state.draggingColumn) === null || _this$grid31 === void 0 ? void 0 : _this$grid31.range),
4081
4152
  formatColumns: this.getCachedPreviewFormatColumns(model.dh, model.columns, conditionalFormats, conditionalFormatPreview,
4082
4153
  // Disable the preview format when we press Back on the format edit page
4083
4154
  ((_openOptions = openOptions[openOptions.length - 1]) === null || _openOptions === void 0 ? void 0 : _openOptions.type) === OptionType.CONDITIONAL_FORMATTING_EDIT ? conditionalFormatEditIndex !== null && conditionalFormatEditIndex !== void 0 ? conditionalFormatEditIndex : undefined : undefined),
@@ -4241,6 +4312,7 @@ _defineProperty(IrisGrid, "defaultProps", {
4241
4312
  userColumnWidthsByName: undefined,
4242
4313
  userRowHeights: EMPTY_MAP,
4243
4314
  onSelectionChanged: () => undefined,
4315
+ onSelectionChange: () => undefined,
4244
4316
  isSelectingColumn: false,
4245
4317
  isSelectingPartition: false,
4246
4318
  isStuckToBottom: false,