@linzjs/step-ag-grid 14.1.2 → 14.3.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.
@@ -1,9 +1,9 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { LuiMiniSpinner, LuiIcon, LuiButton, LuiCheckboxInput, LuiButtonGroup } from '@linzjs/lui';
3
3
  import { AgGridReact } from 'ag-grid-react';
4
- import { negate, isEmpty, xorBy, last, difference, sortBy, findIndex, debounce as debounce$1, delay, partition, omit, pick, groupBy, fromPairs, toPairs, defer as defer$1, sumBy, compact, remove, castArray, flatten, isEqual } from 'lodash-es';
4
+ import { negate, isEmpty, xorBy, last, difference, omit, sortBy, findIndex, debounce as debounce$1, delay, partition, pick, groupBy, fromPairs, toPairs, defer as defer$1, sumBy, compact, remove, castArray, flatten, isEqual } from 'lodash-es';
5
5
  import * as React from 'react';
6
- import { createContext, useContext, useRef, useCallback, useState, useEffect, useMemo, forwardRef, useLayoutEffect, memo, useReducer, cloneElement, useImperativeHandle, Fragment as Fragment$1 } from 'react';
6
+ import { createContext, useContext, useEffect, useRef, useCallback, useState, useMemo, forwardRef, useLayoutEffect, memo, useReducer, cloneElement, useImperativeHandle, Fragment as Fragment$1 } from 'react';
7
7
  import ReactDOM, { unstable_batchedUpdates, flushSync, createPortal } from 'react-dom';
8
8
  import require$$0$1 from 'util';
9
9
  import * as testUtils from 'react-dom/test-utils';
@@ -201,8 +201,8 @@ var GridContext = createContext({
201
201
  console.error("no context provider for getFirstRowId");
202
202
  return -1;
203
203
  },
204
- autoSizeAllColumns: function () {
205
- console.error("no context provider for autoSizeAllColumns");
204
+ autoSizeColumns: function () {
205
+ console.error("no context provider for autoSizeColumns");
206
206
  return null;
207
207
  },
208
208
  sizeColumnsToFit: function () {
@@ -213,6 +213,9 @@ var GridContext = createContext({
213
213
  console.error("no context provider for editingCells");
214
214
  return false;
215
215
  },
216
+ cancelEdit: function () {
217
+ console.error("no context provider for cancelEdit");
218
+ },
216
219
  stopEditing: function () {
217
220
  console.error("no context provider for stopEditing");
218
221
  },
@@ -250,6 +253,9 @@ var GridContext = createContext({
250
253
  },
251
254
  downloadCsv: function () {
252
255
  console.error("no context provider for downloadCsv");
256
+ },
257
+ setOnCellEditingComplete: function () {
258
+ console.error("no context provider for setOnCellEditingComplete");
253
259
  }
254
260
  });
255
261
  var useGridContext = function () { return useContext(GridContext); };
@@ -259,6 +265,10 @@ var GridUpdatingContext = createContext({
259
265
  console.error("Missing GridUpdatingContext");
260
266
  return false;
261
267
  },
268
+ isUpdating: function () {
269
+ console.error("Missing GridUpdatingContext");
270
+ return false;
271
+ },
262
272
  modifyUpdating: function () { return __awaiter(void 0, void 0, void 0, function () {
263
273
  return __generator(this, function (_a) {
264
274
  console.error("Missing GridUpdatingContext");
@@ -268,6 +278,50 @@ var GridUpdatingContext = createContext({
268
278
  updatedDep: 0
269
279
  });
270
280
 
281
+ /**
282
+ * Cancels timeouts on scope being destroyed.
283
+ *
284
+ * This could almost be a debounce, but debounce tracks by function reference, this tracks by hook reference.
285
+ * This could have been implemented using debounce if the callers function was wrapped in useCallback,
286
+ * but there's no way to enforce that, so it would lead to bugs.
287
+ */
288
+ var useTimeoutHook = function () {
289
+ var timeout = useRef();
290
+ /**
291
+ * Clear any pending timeouts.
292
+ */
293
+ var clearTimeouts = function () {
294
+ if (timeout.current) {
295
+ var tc = timeout.current;
296
+ timeout.current = undefined;
297
+ clearTimeout(tc);
298
+ }
299
+ };
300
+ /**
301
+ * Call this when your action has completed.
302
+ */
303
+ var invoke = useCallback(function (fn, waitTimeMs) {
304
+ clearTimeouts();
305
+ timeout.current = setTimeout(fn, waitTimeMs);
306
+ }, []);
307
+ /**
308
+ * Clear timeout on loss of scope.
309
+ */
310
+ useEffect(function () {
311
+ return function () { return clearTimeouts(); };
312
+ }, []);
313
+ return invoke;
314
+ };
315
+ var useIntervalHook = function (_a) {
316
+ var callback = _a.callback, timeoutMs = _a.timeoutMs;
317
+ useEffect(function () {
318
+ var interval = setInterval(callback, timeoutMs);
319
+ return function () {
320
+ clearInterval(interval);
321
+ };
322
+ });
323
+ };
324
+
271
325
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
272
326
 
273
327
  function getDefaultExportFromCjs (x) {
@@ -659,36 +713,67 @@ var GridHeaderSelect = function (_a) {
659
713
  */
660
714
  var Grid = function (_a) {
661
715
  var _b, _c, _d;
662
- var dataTestId = _a["data-testid"], _e = _a.rowSelection, rowSelection = _e === void 0 ? "multiple" : _e, _f = _a.suppressColumnVirtualization, suppressColumnVirtualization = _f === void 0 ? true : _f, _g = _a.theme, theme = _g === void 0 ? "ag-theme-alpine" : _g, _h = _a.sizeColumns, sizeColumns = _h === void 0 ? "auto-skip-headers" : _h, params = __rest(_a, ["data-testid", "rowSelection", "suppressColumnVirtualization", "theme", "sizeColumns"]);
663
- var _j = useContext(GridContext), gridReady = _j.gridReady, setApis = _j.setApis, prePopupOps = _j.prePopupOps, ensureRowVisible = _j.ensureRowVisible, getFirstRowId = _j.getFirstRowId, selectRowsById = _j.selectRowsById, focusByRowById = _j.focusByRowById, ensureSelectedRowIsVisible = _j.ensureSelectedRowIsVisible, autoSizeAllColumns = _j.autoSizeAllColumns, sizeColumnsToFit = _j.sizeColumnsToFit, externallySelectedItemsAreInSync = _j.externallySelectedItemsAreInSync, setExternallySelectedItemsAreInSync = _j.setExternallySelectedItemsAreInSync, isExternalFilterPresent = _j.isExternalFilterPresent, doesExternalFilterPass = _j.doesExternalFilterPass;
664
- var checkUpdating = useContext(GridUpdatingContext).checkUpdating;
716
+ var dataTestId = _a["data-testid"], _e = _a.rowSelection, rowSelection = _e === void 0 ? "multiple" : _e, _f = _a.suppressColumnVirtualization, suppressColumnVirtualization = _f === void 0 ? true : _f, _g = _a.theme, theme = _g === void 0 ? "ag-theme-alpine" : _g, _h = _a.sizeColumns, sizeColumns = _h === void 0 ? "auto" : _h, _j = _a.selectColumnPinned, selectColumnPinned = _j === void 0 ? "left" : _j, params = __rest(_a, ["data-testid", "rowSelection", "suppressColumnVirtualization", "theme", "sizeColumns", "selectColumnPinned"]);
717
+ var _k = useContext(GridContext), gridReady = _k.gridReady, setApis = _k.setApis, prePopupOps = _k.prePopupOps, ensureRowVisible = _k.ensureRowVisible, getFirstRowId = _k.getFirstRowId, selectRowsById = _k.selectRowsById, focusByRowById = _k.focusByRowById, ensureSelectedRowIsVisible = _k.ensureSelectedRowIsVisible, autoSizeColumns = _k.autoSizeColumns, sizeColumnsToFit = _k.sizeColumnsToFit, externallySelectedItemsAreInSync = _k.externallySelectedItemsAreInSync, setExternallySelectedItemsAreInSync = _k.setExternallySelectedItemsAreInSync, isExternalFilterPresent = _k.isExternalFilterPresent, doesExternalFilterPass = _k.doesExternalFilterPass, setOnCellEditingComplete = _k.setOnCellEditingComplete;
718
+ var _l = useContext(GridUpdatingContext), checkUpdating = _l.checkUpdating, updatedDep = _l.updatedDep, isUpdating = _l.isUpdating;
719
+ var gridDivRef = useRef(null);
665
720
  var lastSelectedIds = useRef([]);
666
- var _k = useState(false), staleGrid = _k[0], setStaleGrid = _k[1];
721
+ var _m = useState(false), staleGrid = _m[0], setStaleGrid = _m[1];
667
722
  var postSortRows = usePostSortRowsHook({ setStaleGrid: setStaleGrid });
723
+ /**
724
+ * onContentSize should only be called at maximum twice.
725
+ * Once when an empty grid is loaded.
726
+ * And again when the grid has content.
727
+ */
668
728
  var hasSetContentSize = useRef(false);
669
729
  var hasSetContentSizeEmpty = useRef(false);
730
+ var needsAutoSize = useRef(false);
670
731
  var setInitialContentSize = useCallback(function () {
671
- if ((!isEmpty(params.rowData) && !hasSetContentSize.current) ||
672
- (isEmpty(params.rowData) && !hasSetContentSizeEmpty.current)) {
673
- var skipHeaders = sizeColumns === "auto-skip-headers";
674
- if (sizeColumns === "auto" || skipHeaders) {
675
- // If we aren't skipping headers and there's no data, then don't skip headers
676
- var result = autoSizeAllColumns({ skipHeader: skipHeaders && !isEmpty(params.rowData) });
677
- if (isEmpty(params.rowData)) {
732
+ var _a;
733
+ if (!((_a = gridDivRef.current) === null || _a === void 0 ? void 0 : _a.clientWidth)) {
734
+ // Don't resize grids if they are offscreen as it doesn't work.
735
+ needsAutoSize.current = true;
736
+ return;
737
+ }
738
+ var skipHeader = sizeColumns === "auto-skip-headers" && !isEmpty(params.rowData);
739
+ if (sizeColumns === "auto" || skipHeader) {
740
+ var result = autoSizeColumns({ skipHeader: skipHeader, userSizedColIds: userSizedColIds.current });
741
+ if (isEmpty(params.rowData)) {
742
+ if (!hasSetContentSizeEmpty.current && result && !hasSetContentSize.current) {
678
743
  hasSetContentSizeEmpty.current = true;
744
+ params.onContentSize && params.onContentSize(result);
679
745
  }
680
- else {
746
+ }
747
+ else {
748
+ if (result && !hasSetContentSize.current) {
681
749
  hasSetContentSize.current = true;
750
+ params.onContentSize && params.onContentSize(result);
682
751
  }
683
- params.onContentSize && result && params.onContentSize(result);
684
752
  }
685
753
  }
686
754
  if (sizeColumns !== "none") {
687
755
  sizeColumnsToFit();
688
756
  }
689
- }, [autoSizeAllColumns, params, sizeColumns, sizeColumnsToFit]);
757
+ needsAutoSize.current = false;
758
+ }, [autoSizeColumns, params, sizeColumns, sizeColumnsToFit]);
759
+ /**
760
+ * Auto-size windows that had deferred auto-size
761
+ */
762
+ useIntervalHook({
763
+ callback: function () {
764
+ if (needsAutoSize.current) {
765
+ needsAutoSize.current = false;
766
+ setInitialContentSize();
767
+ }
768
+ },
769
+ timeoutMs: 1000
770
+ });
771
+ var previousGridReady = useRef(gridReady);
690
772
  useEffect(function () {
691
- gridReady && setInitialContentSize();
773
+ if (!previousGridReady.current && gridReady) {
774
+ previousGridReady.current = true;
775
+ setInitialContentSize();
776
+ }
692
777
  }, [gridReady, setInitialContentSize]);
693
778
  /**
694
779
  * On data load select the first row of the grid if required.
@@ -761,12 +846,16 @@ var Grid = function (_a) {
761
846
  }
762
847
  var selectedIds = params.externalSelectedItems.map(function (row) { return row.id; });
763
848
  var lastNewId = last(difference(selectedIds, lastSelectedIds.current));
764
- if (lastNewId != null)
849
+ if (lastNewId != null) {
765
850
  ensureRowVisible(lastNewId);
851
+ }
766
852
  lastSelectedIds.current = selectedIds;
767
853
  selectRowsById(selectedIds);
768
854
  setExternallySelectedItemsAreInSync(true);
769
855
  }, [gridReady, params.externalSelectedItems, ensureRowVisible, selectRowsById, setExternallySelectedItemsAreInSync]);
856
+ /**
857
+ * Combine grid and cell editable into one function
858
+ */
770
859
  var combineEditables = function () {
771
860
  var editables = [];
772
861
  for (var _i = 0; _i < arguments.length; _i++) {
@@ -784,9 +873,10 @@ var Grid = function (_a) {
784
873
  /**
785
874
  * Synchronise externally selected items to grid on externalSelectedItems change
786
875
  */
787
- useEffect(function () {
788
- synchroniseExternallySelectedItemsToGrid();
789
- }, [synchroniseExternallySelectedItemsToGrid]);
876
+ useEffect(synchroniseExternallySelectedItemsToGrid, [synchroniseExternallySelectedItemsToGrid]);
877
+ /**
878
+ * Add selectable column to colDefs. Adjust column defs to block fit for auto sized columns.
879
+ */
790
880
  var columnDefs = useMemo(function () {
791
881
  var adjustColDefs = params.columnDefs.map(function (colDef) {
792
882
  var _a;
@@ -801,6 +891,7 @@ var Grid = function (_a) {
801
891
  editable: false,
802
892
  minWidth: 42,
803
893
  maxWidth: 42,
894
+ pinned: selectColumnPinned,
804
895
  headerComponentParams: {
805
896
  exportable: false
806
897
  },
@@ -826,9 +917,13 @@ var Grid = function (_a) {
826
917
  params.selectable,
827
918
  params.readOnly,
828
919
  (_b = params.defaultColDef) === null || _b === void 0 ? void 0 : _b.editable,
920
+ selectColumnPinned,
829
921
  rowSelection,
830
922
  clickSelectorCheckboxWhenContainingCellClicked,
831
923
  ]);
924
+ /**
925
+ * When grid is ready set the apis to the grid context and sync selected items to grid.
926
+ */
832
927
  var onGridReady = useCallback(function (event) {
833
928
  setApis(event.api, event.columnApi, dataTestId);
834
929
  synchroniseExternallySelectedItemsToGrid();
@@ -838,28 +933,53 @@ var Grid = function (_a) {
838
933
  * This will resize columns when we have at least one row.
839
934
  */
840
935
  var previousRowDataLength = useRef(0);
841
- useEffect(function () {
936
+ var onRowDataChanged = useCallback(function () {
842
937
  var _a, _b;
843
- if (!gridReady)
844
- return;
845
938
  var length = (_b = (_a = params.rowData) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
846
939
  if (previousRowDataLength.current !== length) {
847
- if (previousRowDataLength.current === 0 && length > 0) {
848
- setInitialContentSize();
849
- }
940
+ setInitialContentSize();
850
941
  previousRowDataLength.current = length;
851
942
  }
852
- }, [gridReady, (_c = params.rowData) === null || _c === void 0 ? void 0 : _c.length, setInitialContentSize]);
943
+ if (lastUpdatedDep.current === updatedDep || isEmpty(colIdsEdited.current))
944
+ return;
945
+ lastUpdatedDep.current = updatedDep;
946
+ // Don't update while there are spinners
947
+ if (isUpdating())
948
+ return;
949
+ var skipHeader = sizeColumns === "auto-skip-headers";
950
+ autoSizeColumns({ skipHeader: skipHeader, userSizedColIds: userSizedColIds.current, colIds: colIdsEdited.current });
951
+ colIdsEdited.current.clear();
952
+ }, [autoSizeColumns, isUpdating, (_c = params.rowData) === null || _c === void 0 ? void 0 : _c.length, setInitialContentSize, sizeColumns, updatedDep]);
953
+ /**
954
+ * Show/hide no rows overlay when model changes.
955
+ */
956
+ var isShowingNoRowsOverlay = useRef(false);
853
957
  var onModelUpdated = useCallback(function (event) {
854
- event.api.getDisplayedRowCount() === 0 ? event.api.showNoRowsOverlay() : event.api.hideOverlay();
958
+ if (event.api.getDisplayedRowCount() === 0) {
959
+ if (!isShowingNoRowsOverlay.current) {
960
+ event.api.showNoRowsOverlay();
961
+ isShowingNoRowsOverlay.current = true;
962
+ }
963
+ }
964
+ else {
965
+ if (isShowingNoRowsOverlay.current) {
966
+ event.api.hideOverlay();
967
+ isShowingNoRowsOverlay.current = false;
968
+ }
969
+ }
855
970
  }, []);
971
+ /**
972
+ * Force-refresh all selected rows to re-run class function, to update selection highlighting
973
+ */
856
974
  var refreshSelectedRows = useCallback(function (event) {
857
- // Force-refresh all selected rows to re-run class function, to update selection highlighting
858
975
  event.api.refreshCells({
859
976
  force: true,
860
977
  rowNodes: event.api.getSelectedNodes()
861
978
  });
862
979
  }, []);
980
+ /**
981
+ * Make sure node is selected for editing and start edit
982
+ */
863
983
  var startCellEditing = useCallback(function (event) {
864
984
  var _a;
865
985
  prePopupOps();
@@ -877,16 +997,25 @@ var Grid = function (_a) {
877
997
  });
878
998
  }
879
999
  }, [checkUpdating, prePopupOps]);
1000
+ /**
1001
+ * Handle double click edit
1002
+ */
880
1003
  var onCellDoubleClick = useCallback(function (event) {
881
1004
  if (!invokeEditAction(event))
882
1005
  startCellEditing(event);
883
1006
  }, [startCellEditing]);
1007
+ /**
1008
+ * Handle single click edits
1009
+ */
884
1010
  var onCellClicked = useCallback(function (event) {
885
1011
  var _a, _b;
886
1012
  if ((_b = (_a = event.colDef) === null || _a === void 0 ? void 0 : _a.cellRendererParams) === null || _b === void 0 ? void 0 : _b.singleClickEdit) {
887
1013
  startCellEditing(event);
888
1014
  }
889
1015
  }, [startCellEditing]);
1016
+ /**
1017
+ * If cell has an edit action invoke it (if editable)
1018
+ */
890
1019
  var invokeEditAction = function (e) {
891
1020
  var _a, _b, _c;
892
1021
  var editAction = (_b = (_a = e.colDef) === null || _a === void 0 ? void 0 : _a.cellRendererParams) === null || _b === void 0 ? void 0 : _b.editAction;
@@ -901,6 +1030,9 @@ var Grid = function (_a) {
901
1030
  }
902
1031
  return true;
903
1032
  };
1033
+ /**
1034
+ * Start editing on pressing Enter
1035
+ */
904
1036
  var onCellKeyPress = useCallback(function (e) {
905
1037
  if (e.event.key === "Enter") {
906
1038
  if (!invokeEditAction(e))
@@ -914,7 +1046,82 @@ var Grid = function (_a) {
914
1046
  var columnDefsAdjusted = useMemo(function () {
915
1047
  return columnDefs.map(function (colDef) { return (__assign(__assign({}, colDef), { suppressSizeToFit: (sizeColumns === "auto" || sizeColumns === "auto-skip-headers") && !colDef.flex })); });
916
1048
  }, [columnDefs, sizeColumns]);
917
- return (jsx("div", __assign({ "data-testid": dataTestId, className: clsx("Grid-container", theme, staleGrid && "Grid-sortIsStale", gridReady && params.rowData && "Grid-ready") }, { children: jsx("div", __assign({ style: { flex: 1 } }, { children: jsx(AgGridReact, { animateRows: params.animateRows, rowClassRules: params.rowClassRules, getRowId: function (params) { return "".concat(params.data.id); }, suppressRowClickSelection: true, rowSelection: rowSelection, suppressBrowserResizeObserver: true, onGridSizeChanged: setInitialContentSize, suppressColumnVirtualisation: suppressColumnVirtualization, suppressClickEdit: true, onCellKeyPress: onCellKeyPress, onCellClicked: onCellClicked, onCellDoubleClicked: onCellDoubleClick, onCellEditingStarted: refreshSelectedRows, domLayout: params.domLayout, columnDefs: columnDefsAdjusted, rowData: params.rowData, noRowsOverlayComponent: GridNoRowsOverlay, noRowsOverlayComponentParams: { rowData: params.rowData, noRowsOverlayText: params.noRowsOverlayText }, onModelUpdated: onModelUpdated, onGridReady: onGridReady, onSortChanged: ensureSelectedRowIsVisible, postSortRows: (_d = params.postSortRows) !== null && _d !== void 0 ? _d : postSortRows, onSelectionChanged: synchroniseExternalStateToGridSelection, onColumnMoved: params.onColumnMoved, alwaysShowVerticalScroll: params.alwaysShowVerticalScroll, isExternalFilterPresent: isExternalFilterPresent, doesExternalFilterPass: doesExternalFilterPass, maintainColumnOrder: true }) })) })));
1049
+ /**
1050
+ * Set of colIds that need auto-sizing.
1051
+ */
1052
+ var colIdsEdited = useRef(new Set());
1053
+ /**
1054
+ * When cell editing has completed tag the colId as needing auto-sizing
1055
+ */
1056
+ var onCellEditingStopped = useCallback(function (e) {
1057
+ var skipHeader = sizeColumns === "auto-skip-headers";
1058
+ if (sizeColumns === "auto" || skipHeader) {
1059
+ // This may be wrong as the cell update hasn't completed?
1060
+ var colId = e.colDef.colId;
1061
+ if (colId && !e.colDef.flex) {
1062
+ // This auto-sizes based on updatingContext completing
1063
+ colIdsEdited.current.add(colId);
1064
+ // This auto-sizes immediately in case it was an in place update
1065
+ !isUpdating() &&
1066
+ autoSizeColumns({
1067
+ skipHeader: skipHeader,
1068
+ userSizedColIds: userSizedColIds.current,
1069
+ colIds: [colId]
1070
+ });
1071
+ }
1072
+ }
1073
+ }, [autoSizeColumns, isUpdating, sizeColumns]);
1074
+ var lastUpdatedDep = useRef(updatedDep);
1075
+ /**
1076
+ * If columns are edited, wait for the updating context to complete then auto-size them.
1077
+ */
1078
+ useEffect(function () {
1079
+ if (lastUpdatedDep.current === updatedDep || isEmpty(colIdsEdited.current))
1080
+ return;
1081
+ lastUpdatedDep.current = updatedDep;
1082
+ // Don't update while there are spinners
1083
+ if (isUpdating())
1084
+ return;
1085
+ var skipHeader = sizeColumns === "auto-skip-headers";
1086
+ autoSizeColumns({ skipHeader: skipHeader, userSizedColIds: userSizedColIds.current, colIds: colIdsEdited.current });
1087
+ colIdsEdited.current.clear();
1088
+ }, [autoSizeColumns, updatedDep, sizeColumns, isUpdating]);
1089
+ /**
1090
+ * Resize columns to fit if required on window/container resize
1091
+ */
1092
+ var onGridSizeChanged = useCallback(function () {
1093
+ if (sizeColumns !== "none") {
1094
+ sizeColumnsToFit();
1095
+ }
1096
+ }, [sizeColumns, sizeColumnsToFit]);
1097
+ /**
1098
+ * Set of column Id's that are prevented from auto-sizing as they are user set
1099
+ */
1100
+ var userSizedColIds = useRef(new Set());
1101
+ /**
1102
+ * Lock/unlock column width on user edit/reset.
1103
+ */
1104
+ var onColumnResized = useCallback(function (e) {
1105
+ var _a;
1106
+ var colId = (_a = e.column) === null || _a === void 0 ? void 0 : _a.getColId();
1107
+ if (colId == null)
1108
+ return;
1109
+ switch (e.source) {
1110
+ case "uiColumnDragged":
1111
+ userSizedColIds.current.add(colId);
1112
+ break;
1113
+ case "autosizeColumns":
1114
+ userSizedColIds.current["delete"](colId);
1115
+ break;
1116
+ }
1117
+ }, []);
1118
+ setOnCellEditingComplete(params.onCellEditingComplete);
1119
+ return (jsx("div", __assign({ "data-testid": dataTestId, className: clsx("Grid-container", theme, staleGrid && "Grid-sortIsStale", gridReady && params.rowData && "Grid-ready") }, { children: jsx("div", __assign({ style: { flex: 1 }, ref: gridDivRef }, { children: jsx(AgGridReact, { animateRows: params.animateRows, rowClassRules: params.rowClassRules, getRowId: function (params) { return "".concat(params.data.id); }, suppressRowClickSelection: true, rowSelection: rowSelection, suppressBrowserResizeObserver: true, onGridSizeChanged: onGridSizeChanged, suppressColumnVirtualisation: suppressColumnVirtualization, suppressClickEdit: true, onColumnVisible: function () {
1120
+ setInitialContentSize();
1121
+ }, onRowDataChanged: onRowDataChanged, onCellKeyPress: onCellKeyPress, onCellClicked: onCellClicked, onCellDoubleClicked: onCellDoubleClick, onCellEditingStarted: refreshSelectedRows, domLayout: params.domLayout, onCellEditingStopped: onCellEditingStopped, onColumnResized: onColumnResized, defaultColDef: __assign({ minWidth: 48 }, omit(params.defaultColDef, ["editable"])), columnDefs: columnDefsAdjusted, rowData: params.rowData, noRowsOverlayComponent: GridNoRowsOverlay, noRowsOverlayComponentParams: {
1122
+ rowData: params.rowData,
1123
+ noRowsOverlayText: params.noRowsOverlayText
1124
+ }, onModelUpdated: onModelUpdated, onGridReady: onGridReady, onSortChanged: ensureSelectedRowIsVisible, postSortRows: (_d = params.postSortRows) !== null && _d !== void 0 ? _d : postSortRows, onSelectionChanged: synchroniseExternalStateToGridSelection, onColumnMoved: params.onColumnMoved, alwaysShowVerticalScroll: params.alwaysShowVerticalScroll, isExternalFilterPresent: isExternalFilterPresent, doesExternalFilterPass: doesExternalFilterPass, maintainColumnOrder: true }) })) })));
918
1125
  };
919
1126
 
920
1127
  var GridPopoverContext = createContext({
@@ -1054,7 +1261,7 @@ var generateFilterGetter = function (field, filterValueGetter, valueFormatter) {
1054
1261
  * All cells should use this.
1055
1262
  */
1056
1263
  var GridCell = function (props, custom) {
1057
- var _a, _b, _c;
1264
+ var _a, _b, _c, _d;
1058
1265
  // Generate a default filter value getter which uses the formatted value plus
1059
1266
  // the editable value if it's a string and different from the formatted value.
1060
1267
  // This is so that e.g. bearings can be searched for by DMS or raw number.
@@ -1063,12 +1270,12 @@ var GridCell = function (props, custom) {
1063
1270
  var exportable = props.exportable;
1064
1271
  // Can't leave this here ag-grid will complain
1065
1272
  delete props.exportable;
1066
- return __assign(__assign(__assign(__assign(__assign(__assign({ colId: (_a = props.field) !== null && _a !== void 0 ? _a : props.field, headerTooltip: props.headerName, sortable: !!((props === null || props === void 0 ? void 0 : props.field) || (props === null || props === void 0 ? void 0 : props.valueGetter)), resizable: true, minWidth: props.flex ? 150 : 48, editable: (_b = props.editable) !== null && _b !== void 0 ? _b : false }, ((custom === null || custom === void 0 ? void 0 : custom.editor) && {
1273
+ return __assign(__assign(__assign(__assign(__assign(__assign({ colId: (_a = props.field) !== null && _a !== void 0 ? _a : props.field, headerTooltip: props.headerName, sortable: !!((props === null || props === void 0 ? void 0 : props.field) || (props === null || props === void 0 ? void 0 : props.valueGetter)), resizable: true, editable: (_b = props.editable) !== null && _b !== void 0 ? _b : false }, ((custom === null || custom === void 0 ? void 0 : custom.editor) && {
1067
1274
  cellClassRules: GridCellMultiSelectClassRules,
1068
1275
  editable: (_c = props.editable) !== null && _c !== void 0 ? _c : true,
1069
1276
  cellEditor: GenericCellEditorComponentWrapper(custom === null || custom === void 0 ? void 0 : custom.editor)
1070
1277
  })), { suppressKeyboardEvent: suppressCellKeyboardEvents }), ((custom === null || custom === void 0 ? void 0 : custom.editorParams) && {
1071
- cellEditorParams: __assign(__assign({}, custom.editorParams), { multiEdit: custom.multiEdit })
1278
+ cellEditorParams: __assign(__assign({}, custom.editorParams), { multiEdit: custom.multiEdit, preventAutoEdit: (_d = custom.preventAutoEdit) !== null && _d !== void 0 ? _d : false })
1072
1279
  })), {
1073
1280
  // If there's a valueFormatter and no filterValueGetter then create a filterValueGetter
1074
1281
  filterValueGetter: filterValueGetter,
@@ -2274,7 +2481,21 @@ var MenuList = function (_a) {
2274
2481
  }
2275
2482
  : undefined;
2276
2483
  }, [dontShrinkIfDirectionIsTop, expandedDirection, isSubmenuOpen]);
2277
- return (jsxs("ul", __assign({ role: "menu", "aria-label": ariaLabel }, mergeProps({ onKeyDown: onKeyDown, onAnimationEnd: onAnimationEnd }, restProps), commonProps(isDisabled), { ref: useCombinedRef(externalRef, menuRef), className: useBEM({ block: menuClass, modifiers: modifiers, className: menuClassName }), style: __assign(__assign(__assign(__assign({}, menuStyle), overflowStyle), dontShrinkOps), { margin: 0, display: state === "closed" ? "none" : undefined, position: "absolute", left: menuPosition.x, top: menuPosition.y }) }, { children: [jsx("div", { ref: focusRef, tabIndex: -1, style: { position: "absolute", left: 0, top: 0 } }), arrow && (jsx("div", { className: _arrowClass, style: __assign(__assign({}, arrowStyle), { position: "absolute", left: arrowPosition.x, top: arrowPosition.y }), ref: arrowRef })), jsx(MenuListContext.Provider, __assign({ value: listContext }, { children: jsx(MenuListItemContext.Provider, __assign({ value: itemContext }, { children: jsx(HoverItemContext.Provider, __assign({ value: hoverItem }, { children: children })) })) }))] })));
2484
+ return (jsxs("ul", __assign({ role: "menu", "aria-label": ariaLabel }, mergeProps({ onKeyDown: onKeyDown, onAnimationEnd: onAnimationEnd }, restProps), commonProps(isDisabled), { ref: useCombinedRef(externalRef, menuRef), className: useBEM({ block: menuClass, modifiers: modifiers, className: menuClassName }), style: __assign(__assign(__assign(__assign({}, menuStyle), overflowStyle), dontShrinkOps), { margin: 0, display: state === "closed" ? "none" : undefined, position: "absolute", left: menuPosition.x, top: menuPosition.y }) }, { children: [jsx("div", { ref: focusRef, tabIndex: -1, style: { position: "absolute", left: 0, top: 0 }, onKeyDown: function (event) {
2485
+ if (event.key == "Tab") {
2486
+ event.preventDefault();
2487
+ event.stopPropagation();
2488
+ safeCall(onClose, {
2489
+ key: event.key,
2490
+ shiftKey: event.shiftKey,
2491
+ reason: event.key === "Tab"
2492
+ ? event.shiftKey
2493
+ ? CloseReason.TAB_BACKWARD
2494
+ : CloseReason.TAB_FORWARD
2495
+ : CloseReason.CLICK
2496
+ });
2497
+ }
2498
+ } }), arrow && (jsx("div", { className: _arrowClass, style: __assign(__assign({}, arrowStyle), { position: "absolute", left: arrowPosition.x, top: arrowPosition.y }), ref: arrowRef })), jsx(MenuListContext.Provider, __assign({ value: listContext }, { children: jsx(MenuListItemContext.Provider, __assign({ value: itemContext }, { children: jsx(HoverItemContext.Provider, __assign({ value: hoverItem }, { children: children })) })) }))] })));
2278
2499
  };
2279
2500
 
2280
2501
  var ControlledMenuFr = function (_a, externalRef) {
@@ -2991,41 +3212,6 @@ var GridFilters = function (_a) {
2991
3212
  return jsx("div", __assign({ className: "Grid-container-filters" }, { children: children }));
2992
3213
  };
2993
3214
 
2994
- /**
2995
- * Cancels timeouts on scope being destroyed.
2996
- *
2997
- * This could almost be a debounce, but debounce tracks by function reference, this tracks by hook reference.
2998
- * This could have been implemented using debounce if the callers function was wrapped in useCallback,
2999
- * but there's no way to enforce that, so it would lead to bugs.
3000
- */
3001
- var useTimeoutHook = function () {
3002
- var timeout = useRef();
3003
- /**
3004
- * Clear any pending timeouts.
3005
- */
3006
- var clearTimeouts = function () {
3007
- if (timeout.current) {
3008
- var tc = timeout.current;
3009
- timeout.current = undefined;
3010
- clearTimeout(tc);
3011
- }
3012
- };
3013
- /**
3014
- * Call this when your action has completed.
3015
- */
3016
- var invoke = useCallback(function (fn, waitTimeMs) {
3017
- clearTimeouts();
3018
- timeout.current = setTimeout(fn, waitTimeMs);
3019
- }, []);
3020
- /**
3021
- * Clear timeout on loss of scope.
3022
- */
3023
- useEffect(function () {
3024
- return function () { return clearTimeouts(); };
3025
- }, []);
3026
- return invoke;
3027
- };
3028
-
3029
3215
  /**
3030
3216
  * Defers state change up to a minimum time since last state change.
3031
3217
  */
@@ -3349,10 +3535,10 @@ var textMatch = function (text, filter) {
3349
3535
  };
3350
3536
 
3351
3537
  var useGridPopoverHook = function (props) {
3352
- var stopEditing = useContext(GridContext).stopEditing;
3353
- var _a = useGridPopoverContext(), anchorRef = _a.anchorRef, saving = _a.saving, updateValue = _a.updateValue;
3538
+ var _a = useContext(GridContext), stopEditing = _a.stopEditing, cancelEdit = _a.cancelEdit;
3539
+ var _b = useGridPopoverContext(), anchorRef = _b.anchorRef, saving = _b.saving, updateValue = _b.updateValue;
3354
3540
  var saveButtonRef = useRef(null);
3355
- var _b = useState(false), isOpen = _b[0], setOpen = _b[1];
3541
+ var _c = useState(false), isOpen = _c[0], setOpen = _c[1];
3356
3542
  useEffect(function () {
3357
3543
  setOpen(true);
3358
3544
  }, []);
@@ -3361,14 +3547,14 @@ var useGridPopoverHook = function (props) {
3361
3547
  switch (_a.label) {
3362
3548
  case 0:
3363
3549
  if (reason == CloseReason.CANCEL) {
3364
- stopEditing();
3550
+ cancelEdit();
3365
3551
  return [2 /*return*/];
3366
3552
  }
3367
3553
  if (props.invalid && props.invalid()) {
3368
3554
  return [2 /*return*/];
3369
3555
  }
3370
3556
  if (!!props.save) return [3 /*break*/, 1];
3371
- stopEditing();
3557
+ cancelEdit();
3372
3558
  return [3 /*break*/, 3];
3373
3559
  case 1:
3374
3560
  if (!props.save) return [3 /*break*/, 3];
@@ -3385,7 +3571,7 @@ var useGridPopoverHook = function (props) {
3385
3571
  case 3: return [2 /*return*/];
3386
3572
  }
3387
3573
  });
3388
- }); }, [props, stopEditing, updateValue]);
3574
+ }); }, [cancelEdit, props, stopEditing, updateValue]);
3389
3575
  var popoverWrapper = useCallback(function (children) {
3390
3576
  return (jsx(Fragment, { children: anchorRef.current && (jsxs(ControlledMenu, __assign({ state: isOpen ? "open" : "closed", portal: true, unmountOnClose: true, anchorRef: anchorRef, saveButtonRef: saveButtonRef, menuClassName: "step-ag-grid-react-menu", onClose: function (event) {
3391
3577
  // Prevent menu from closing when modals are invoked
@@ -3475,15 +3661,7 @@ var GridFormDropDown = function (props) {
3475
3661
  }
3476
3662
  : item;
3477
3663
  });
3478
- if (props.filtered) {
3479
- // This is needed otherwise when filter input is rendered and sets autofocus
3480
- // the mouse up of the double click edit triggers the cell to cancel editing
3481
- setOptions(optionsList);
3482
- //delay(() => setOptions(optionsList), 100);
3483
- }
3484
- else {
3485
- setOptions(optionsList);
3486
- }
3664
+ setOptions(optionsList);
3487
3665
  }
3488
3666
  return [2 /*return*/];
3489
3667
  }
@@ -4411,7 +4589,7 @@ var GridPopoverMenu = function (colDef, custom) {
4411
4589
  return GridCell(__assign(__assign({ minWidth: 48, maxWidth: 48, width: 40, editable: colDef.editable != null ? colDef.editable : true, exportable: false, cellStyle: { flex: 1, justifyContent: "center" }, cellRenderer: GridRenderPopoutMenuCell }, colDef), { cellRendererParams: {
4412
4590
  // Menus open on single click, this parameter is picked up in Grid.tsx
4413
4591
  singleClickEdit: true
4414
- } }), __assign({ editor: GridFormPopoverMenu }, custom));
4592
+ } }), __assign({ editor: GridFormPopoverMenu, preventAutoEdit: true }, custom));
4415
4593
  };
4416
4594
 
4417
4595
  var GridPopoverEditBearingLike = function (colDef, props) {
@@ -4503,14 +4681,14 @@ var GridContextProvider = function (props) {
4503
4681
  * @return true if row is found, else false
4504
4682
  */
4505
4683
  var ensureRowVisible = useCallback(function (id) {
4506
- return gridApiOp(function (gridApi) {
4507
- var node = gridApi.getRowNode("".concat(id));
4508
- if (!node)
4509
- return false;
4510
- gridApi.ensureNodeVisible(node);
4511
- return true;
4512
- });
4513
- }, [gridApiOp]);
4684
+ if (!gridApi)
4685
+ return false;
4686
+ var node = gridApi === null || gridApi === void 0 ? void 0 : gridApi.getRowNode("".concat(id));
4687
+ if (!node)
4688
+ return false;
4689
+ defer$1(function () { return gridApi.ensureNodeVisible(node); });
4690
+ return true;
4691
+ }, [gridApi]);
4514
4692
  var getFirstRowId = useCallback(function () {
4515
4693
  var id = 0;
4516
4694
  try {
@@ -4622,17 +4800,16 @@ var GridContextProvider = function (props) {
4622
4800
  var rowsThatNeedSelecting = sortBy(rowNodes.filter(function (node) { return !node.isSelected(); }), function (node) { return node.data.id; });
4623
4801
  var firstNode = rowsThatNeedSelecting[0];
4624
4802
  if (firstNode) {
4625
- gridApi.ensureNodeVisible(firstNode);
4803
+ defer$1(function () { return gridApi.ensureNodeVisible(firstNode); });
4626
4804
  var colDefs = gridApi.getColumnDefs();
4627
- if (colDefs && colDefs.length) {
4805
+ if (colDefs === null || colDefs === void 0 ? void 0 : colDefs.length) {
4628
4806
  var col = colDefs[0]; // We don't support ColGroupDef
4629
4807
  var rowIndex_1 = firstNode.rowIndex;
4630
4808
  if (rowIndex_1 != null && col != null) {
4631
4809
  var colId_1 = col.colId;
4632
4810
  // We need to make sure we aren't currently editing a cell otherwise tests will fail
4633
4811
  // as they will start to edit the cell before this stuff has a chance to run
4634
- colId_1 != null &&
4635
- defer$1(function () { return isEmpty(gridApi.getEditingCells()) && gridApi.setFocusedCell(rowIndex_1, colId_1); });
4812
+ colId_1 && defer$1(function () { return isEmpty(gridApi.getEditingCells()) && gridApi.setFocusedCell(rowIndex_1, colId_1); });
4636
4813
  }
4637
4814
  }
4638
4815
  }
@@ -4727,45 +4904,97 @@ var GridContextProvider = function (props) {
4727
4904
  var selectedNodes = gridApi.getSelectedNodes();
4728
4905
  if (isEmpty(selectedNodes))
4729
4906
  return;
4730
- gridApi.ensureNodeVisible(last(selectedNodes));
4907
+ defer$1(function () { return gridApi.ensureNodeVisible(last(selectedNodes)); });
4731
4908
  });
4732
4909
  }, [gridApiOp]);
4733
4910
  /**
4734
4911
  * Resize columns to fit container
4735
4912
  */
4736
- var autoSizeAllColumns = useCallback(function (_a) {
4737
- var skipHeader = _a.skipHeader;
4738
- if (columnApi) {
4739
- columnApi.autoSizeAllColumns(skipHeader);
4740
- return {
4741
- width: sumBy(columnApi.getColumnState().filter(function (col) { return col.hide !== true; }), "width")
4742
- };
4743
- }
4744
- return null;
4913
+ var autoSizeColumns = useCallback(function (_a) {
4914
+ var _b = _a === void 0 ? {} : _a, skipHeader = _b.skipHeader, colIds = _b.colIds, userSizedColIds = _b.userSizedColIds;
4915
+ if (!columnApi)
4916
+ return null;
4917
+ var colIdsSet = colIds instanceof Set ? colIds : new Set(colIds !== null && colIds !== void 0 ? colIds : []);
4918
+ columnApi.getColumnState().forEach(function (col) {
4919
+ var colId = col.colId;
4920
+ if ((isEmpty(colIdsSet) || colIdsSet.has(colId)) && !(userSizedColIds === null || userSizedColIds === void 0 ? void 0 : userSizedColIds.has(colId))) {
4921
+ columnApi.autoSizeColumn(colId, skipHeader);
4922
+ }
4923
+ });
4924
+ return {
4925
+ width: sumBy(columnApi.getColumnState().filter(function (col) { return !col.hide; }), "width")
4926
+ };
4745
4927
  }, [columnApi]);
4746
4928
  /**
4747
4929
  * Resize columns to fit container
4748
4930
  */
4749
4931
  var sizeColumnsToFit = useCallback(function () {
4750
- if (gridApi) {
4751
- gridApi.sizeColumnsToFit();
4752
- }
4932
+ gridApi && gridApi.sizeColumnsToFit();
4753
4933
  }, [gridApi]);
4754
4934
  var stopEditing = useCallback(function () {
4935
+ if (!gridApi)
4936
+ return;
4755
4937
  if (prePopupFocusedCell.current) {
4756
4938
  gridApi === null || gridApi === void 0 ? void 0 : gridApi.setFocusedCell(prePopupFocusedCell.current.rowIndex, prePopupFocusedCell.current.column);
4757
4939
  }
4758
- gridApiOp(function (gridApi) { return gridApi.stopEditing(); });
4759
- }, [gridApi, gridApiOp]);
4760
- var selectNextCell = useCallback(function (tabDirection) {
4761
- if (tabDirection === void 0) { tabDirection = 0; }
4762
- gridApiOp(function (gridApi) {
4763
- if (tabDirection == 1)
4764
- gridApi.tabToNextCell();
4765
- if (tabDirection == -1)
4766
- gridApi.tabToPreviousCell();
4767
- });
4768
- }, [gridApiOp]);
4940
+ gridApi.stopEditing();
4941
+ }, [gridApi]);
4942
+ /**
4943
+ * This differs from stopEdit in that it will also invoke cellEditingCompleteCallback
4944
+ */
4945
+ var cancelEdit = useCallback(function () {
4946
+ stopEditing();
4947
+ cellEditingCompleteCallbackRef.current && cellEditingCompleteCallbackRef.current();
4948
+ }, [stopEditing]);
4949
+ var cellEditingCompleteCallbackRef = useRef();
4950
+ var setOnCellEditingComplete = useCallback(function (cellEditingCompleteCallback) {
4951
+ cellEditingCompleteCallbackRef.current = cellEditingCompleteCallback;
4952
+ }, []);
4953
+ /**
4954
+ * Returns true if an editable cell on same row was selected, else false.
4955
+ */
4956
+ var selectNextEditableCell = useCallback(function (tabDirection) {
4957
+ // Pretend it succeeded to prevent unwanted cellEditingCompleteCallback
4958
+ if (!gridApi)
4959
+ return true;
4960
+ var focusedCellIsEditable = function () {
4961
+ var _a, _b;
4962
+ var focusedCell = gridApi.getFocusedCell();
4963
+ var nextColumn = focusedCell === null || focusedCell === void 0 ? void 0 : focusedCell.column;
4964
+ var nextColDef = nextColumn === null || nextColumn === void 0 ? void 0 : nextColumn.getColDef();
4965
+ var rowNode = focusedCell && gridApi.getDisplayedRowAtIndex(focusedCell === null || focusedCell === void 0 ? void 0 : focusedCell.rowIndex);
4966
+ return (!!(rowNode && nextColumn && nextColDef) &&
4967
+ nextColumn.isCellEditable(rowNode) &&
4968
+ !((_a = nextColDef.cellEditorParams) === null || _a === void 0 ? void 0 : _a.preventAutoEdit) &&
4969
+ !((_b = nextColDef.cellRendererParams) === null || _b === void 0 ? void 0 : _b.editAction));
4970
+ };
4971
+ var foundEditableCell = false;
4972
+ // Just in case I've missed something, we don't want the loop to hang everything
4973
+ var maxIterations = 50;
4974
+ var preRow = null;
4975
+ var postRow = null;
4976
+ do {
4977
+ preRow = gridApi.getFocusedCell();
4978
+ tabDirection === 1 ? gridApi.tabToNextCell() : gridApi.tabToPreviousCell();
4979
+ postRow = gridApi.getFocusedCell();
4980
+ foundEditableCell = focusedCellIsEditable();
4981
+ } while ((preRow === null || preRow === void 0 ? void 0 : preRow.rowIndex) === (postRow === null || postRow === void 0 ? void 0 : postRow.rowIndex) &&
4982
+ (preRow === null || preRow === void 0 ? void 0 : preRow.column) !== (postRow === null || postRow === void 0 ? void 0 : postRow.column) &&
4983
+ !foundEditableCell &&
4984
+ maxIterations-- > 0);
4985
+ if (foundEditableCell) {
4986
+ prePopupOps();
4987
+ var focusedCell = gridApi === null || gridApi === void 0 ? void 0 : gridApi.getFocusedCell();
4988
+ if (focusedCell) {
4989
+ gridApi.startEditingCell({
4990
+ rowIndex: focusedCell.rowIndex,
4991
+ colKey: focusedCell.column.getColId()
4992
+ });
4993
+ return false;
4994
+ }
4995
+ }
4996
+ return true;
4997
+ }, [gridApi, prePopupOps]);
4769
4998
  var updatingCells = useCallback(function (props, fnUpdate, setSaving, tabDirection) { return __awaiter(void 0, void 0, void 0, function () {
4770
4999
  return __generator(this, function (_a) {
4771
5000
  switch (_a.label) {
@@ -4812,12 +5041,13 @@ var GridContextProvider = function (props) {
4812
5041
  setSaving && setSaving(false);
4813
5042
  }
4814
5043
  postPopupFocusedCell = gridApi.getFocusedCell();
4815
- if (tabDirection &&
4816
- prePopupFocusedCell.current &&
5044
+ if (prePopupFocusedCell.current &&
4817
5045
  postPopupFocusedCell &&
4818
5046
  prePopupFocusedCell.current.rowIndex == postPopupFocusedCell.rowIndex &&
4819
5047
  prePopupFocusedCell.current.column.getColId() == postPopupFocusedCell.column.getColId()) {
4820
- selectNextCell(tabDirection);
5048
+ if (!tabDirection || selectNextEditableCell(tabDirection)) {
5049
+ cellEditingCompleteCallbackRef.current && cellEditingCompleteCallbackRef.current();
5050
+ }
4821
5051
  }
4822
5052
  return [2 /*return*/, ok];
4823
5053
  }
@@ -4826,7 +5056,7 @@ var GridContextProvider = function (props) {
4826
5056
  case 1: return [2 /*return*/, _a.sent()];
4827
5057
  }
4828
5058
  });
4829
- }); }, [gridApiOp, modifyUpdating, selectNextCell]);
5059
+ }); }, [gridApiOp, modifyUpdating, selectNextEditableCell]);
4830
5060
  var redrawRows = useCallback(function (rowNodes) {
4831
5061
  gridApiOp(function (gridApi) {
4832
5062
  gridApi.redrawRows(rowNodes ? { rowNodes: rowNodes } : undefined);
@@ -4864,11 +5094,11 @@ var GridContextProvider = function (props) {
4864
5094
  }, [gridApi]);
4865
5095
  var addExternalFilter = function (filter) {
4866
5096
  externalFilters.current.push(filter);
4867
- onFilterChanged();
5097
+ onFilterChanged().then();
4868
5098
  };
4869
5099
  var removeExternalFilter = function (filter) {
4870
5100
  remove(externalFilters.current, function (v) { return v === filter; });
4871
- onFilterChanged();
5101
+ onFilterChanged().then();
4872
5102
  };
4873
5103
  var isExternalFilterPresent = function () { return externalFilters.current.length > 0; };
4874
5104
  var doesExternalFilterPass = function (node) {
@@ -4919,8 +5149,9 @@ var GridContextProvider = function (props) {
4919
5149
  ensureRowVisible: ensureRowVisible,
4920
5150
  ensureSelectedRowIsVisible: ensureSelectedRowIsVisible,
4921
5151
  sizeColumnsToFit: sizeColumnsToFit,
4922
- autoSizeAllColumns: autoSizeAllColumns,
5152
+ autoSizeColumns: autoSizeColumns,
4923
5153
  stopEditing: stopEditing,
5154
+ cancelEdit: cancelEdit,
4924
5155
  updatingCells: updatingCells,
4925
5156
  redrawRows: redrawRows,
4926
5157
  externallySelectedItemsAreInSync: externallySelectedItemsAreInSync,
@@ -4930,7 +5161,8 @@ var GridContextProvider = function (props) {
4930
5161
  removeExternalFilter: removeExternalFilter,
4931
5162
  isExternalFilterPresent: isExternalFilterPresent,
4932
5163
  doesExternalFilterPass: doesExternalFilterPass,
4933
- downloadCsv: downloadCsv
5164
+ downloadCsv: downloadCsv,
5165
+ setOnCellEditingComplete: setOnCellEditingComplete
4934
5166
  } }, { children: props.children })));
4935
5167
  };
4936
5168
  /**
@@ -4970,6 +5202,7 @@ var downloadCsvUseValueFormattersProcessCellCallback = function (params) {
4970
5202
  return encodeToString(params.value);
4971
5203
  }
4972
5204
  var result = valueFormatter(__assign(__assign({}, params), { data: (_b = params.node) === null || _b === void 0 ? void 0 : _b.data, colDef: colDef }));
5205
+ // type may not be string due to casting, leave the type check in
4973
5206
  if (params.value != null && typeof result !== "string") {
4974
5207
  console.error("downloadCsv: valueFormatter is returning non string values, colDef:\", colId: ".concat(colDef.colId));
4975
5208
  }
@@ -4984,11 +5217,15 @@ var GridUpdatingContextProvider = function (props) {
4984
5217
  var resetUpdating = function () {
4985
5218
  var mergedUpdatingBlocks = {};
4986
5219
  for (var key in updatingBlocks.current) {
4987
- mergedUpdatingBlocks[key] = flatten(updatingBlocks.current[key]);
5220
+ var arr = flatten(updatingBlocks.current[key]);
5221
+ if (arr.length) {
5222
+ mergedUpdatingBlocks[key] = arr;
5223
+ }
4988
5224
  }
4989
5225
  updating.current = mergedUpdatingBlocks;
4990
5226
  setUpdatedDep(function (updatedDep) { return updatedDep + 1; });
4991
5227
  };
5228
+ var isUpdating = function () { return !isEmpty(updating.current); };
4992
5229
  var modifyUpdating = function (fields, ids, fn) { return __awaiter(void 0, void 0, void 0, function () {
4993
5230
  var idRef;
4994
5231
  return __generator(this, function (_a) {
@@ -5016,7 +5253,7 @@ var GridUpdatingContextProvider = function (props) {
5016
5253
  var checkUpdating = function (fields, id) {
5017
5254
  return castArray(fields).some(function (f) { var _a; return (_a = updating.current[f]) === null || _a === void 0 ? void 0 : _a.includes(id); });
5018
5255
  };
5019
- return (jsx(GridUpdatingContext.Provider, __assign({ value: { modifyUpdating: modifyUpdating, checkUpdating: checkUpdating, updatedDep: updatedDep } }, { children: props.children })));
5256
+ return (jsx(GridUpdatingContext.Provider, __assign({ value: { modifyUpdating: modifyUpdating, checkUpdating: checkUpdating, isUpdating: isUpdating, updatedDep: updatedDep } }, { children: props.children })));
5020
5257
  };
5021
5258
 
5022
5259
  var css_248z = ".ActionButton{align-items:center;display:flex}.ActionButton-minimal.lui-button-lg.lui-button-icon-right{padding-right:38px}.ActionButton.lui-button-lg.lui-button-icon-right:not(.ActionButton-tight) .LuiIcon{margin:0 4px}.ActionButton.ActionButton-tight.lui-button-lg.lui-button-icon-right .LuiIcon{margin:0}.ActionButton-iconOnly.lui-button-lg.lui-button-icon-right:not(.ActionButton-tight){padding:8px 5px}.ActionButton-iconOnly.lui-button-lg.lui-button-icon-right.ActionButton-tight{padding:0}.ActionButton-minimalArea{position:relative}.ActionButton-minimalAreaDisplay{position:absolute}.ActionButton-minimalAreaExpand{visibility:hidden}.ActionButton-inProgress.lui-button-lg.lui-button-icon-right{background-color:#e2f3f7;color:#007198;cursor:progress}.ActionButton-inProgress.lui-button-lg.lui-button-icon-right svg *{fill:#0000}.ActionButton-fill{justify-content:center;width:100%}";