@linzjs/step-ag-grid 25.0.1 → 26.0.1

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.
@@ -8,38 +8,6 @@ var lodashEs = require('lodash-es');
8
8
  var React = require('react');
9
9
  var reactDom = require('react-dom');
10
10
 
11
- /**
12
- * AgGrid checkbox select does not pass clicks within cell but not on the checkbox to checkbox.
13
- * This passes the event to the checkbox when you click anywhere in the cell.
14
- */
15
- const clickInputWhenContainingCellClicked = (params) => {
16
- const { data, event, colDef } = params;
17
- if (!data || !event)
18
- return;
19
- const element = event.target;
20
- // Already handled
21
- if (element.closest('.GridCell-readonly') ||
22
- (['BUTTON', 'INPUT'].includes(element?.tagName) && element.closest('.ag-cell-inline-editing'))) {
23
- return;
24
- }
25
- const row = element.closest('[row-id]');
26
- if (!row)
27
- return;
28
- const colId = colDef.colId;
29
- if (!colId)
30
- return;
31
- const clickInput = () => {
32
- const cell = row.querySelector(`[col-id='${colId}']`);
33
- if (!cell)
34
- return;
35
- const input = cell.querySelector('input, button');
36
- if (!input)
37
- return;
38
- input?.dispatchEvent(event);
39
- };
40
- setTimeout(clickInput, 20);
41
- };
42
-
43
11
  /**
44
12
  * If loading is true this returns a loading spinner, otherwise it returns its children.
45
13
  */
@@ -64,14 +32,384 @@ function getDefaultExportFromCjs (x) {
64
32
  * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
65
33
  */
66
34
 
67
- /** Detect free variable `global` from Node.js. */
68
- var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
35
+ var lodash_debounce;
36
+ var hasRequiredLodash_debounce;
37
+
38
+ function requireLodash_debounce () {
39
+ if (hasRequiredLodash_debounce) return lodash_debounce;
40
+ hasRequiredLodash_debounce = 1;
41
+ /** Used as the `TypeError` message for "Functions" methods. */
42
+ var FUNC_ERROR_TEXT = 'Expected a function';
43
+
44
+ /** Used as references for various `Number` constants. */
45
+ var NAN = 0 / 0;
46
+
47
+ /** `Object#toString` result references. */
48
+ var symbolTag = '[object Symbol]';
49
+
50
+ /** Used to match leading and trailing whitespace. */
51
+ var reTrim = /^\s+|\s+$/g;
52
+
53
+ /** Used to detect bad signed hexadecimal string values. */
54
+ var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
55
+
56
+ /** Used to detect binary string values. */
57
+ var reIsBinary = /^0b[01]+$/i;
58
+
59
+ /** Used to detect octal string values. */
60
+ var reIsOctal = /^0o[0-7]+$/i;
61
+
62
+ /** Built-in method references without a dependency on `root`. */
63
+ var freeParseInt = parseInt;
64
+
65
+ /** Detect free variable `global` from Node.js. */
66
+ var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
67
+
68
+ /** Detect free variable `self`. */
69
+ var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
70
+
71
+ /** Used as a reference to the global object. */
72
+ var root = freeGlobal || freeSelf || Function('return this')();
73
+
74
+ /** Used for built-in method references. */
75
+ var objectProto = Object.prototype;
76
+
77
+ /**
78
+ * Used to resolve the
79
+ * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
80
+ * of values.
81
+ */
82
+ var objectToString = objectProto.toString;
83
+
84
+ /* Built-in method references for those with the same name as other `lodash` methods. */
85
+ var nativeMax = Math.max,
86
+ nativeMin = Math.min;
87
+
88
+ /**
89
+ * Gets the timestamp of the number of milliseconds that have elapsed since
90
+ * the Unix epoch (1 January 1970 00:00:00 UTC).
91
+ *
92
+ * @static
93
+ * @memberOf _
94
+ * @since 2.4.0
95
+ * @category Date
96
+ * @returns {number} Returns the timestamp.
97
+ * @example
98
+ *
99
+ * _.defer(function(stamp) {
100
+ * console.log(_.now() - stamp);
101
+ * }, _.now());
102
+ * // => Logs the number of milliseconds it took for the deferred invocation.
103
+ */
104
+ var now = function() {
105
+ return root.Date.now();
106
+ };
69
107
 
70
- /** Detect free variable `self`. */
71
- var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
108
+ /**
109
+ * Creates a debounced function that delays invoking `func` until after `wait`
110
+ * milliseconds have elapsed since the last time the debounced function was
111
+ * invoked. The debounced function comes with a `cancel` method to cancel
112
+ * delayed `func` invocations and a `flush` method to immediately invoke them.
113
+ * Provide `options` to indicate whether `func` should be invoked on the
114
+ * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
115
+ * with the last arguments provided to the debounced function. Subsequent
116
+ * calls to the debounced function return the result of the last `func`
117
+ * invocation.
118
+ *
119
+ * **Note:** If `leading` and `trailing` options are `true`, `func` is
120
+ * invoked on the trailing edge of the timeout only if the debounced function
121
+ * is invoked more than once during the `wait` timeout.
122
+ *
123
+ * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
124
+ * until to the next tick, similar to `setTimeout` with a timeout of `0`.
125
+ *
126
+ * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
127
+ * for details over the differences between `_.debounce` and `_.throttle`.
128
+ *
129
+ * @static
130
+ * @memberOf _
131
+ * @since 0.1.0
132
+ * @category Function
133
+ * @param {Function} func The function to debounce.
134
+ * @param {number} [wait=0] The number of milliseconds to delay.
135
+ * @param {Object} [options={}] The options object.
136
+ * @param {boolean} [options.leading=false]
137
+ * Specify invoking on the leading edge of the timeout.
138
+ * @param {number} [options.maxWait]
139
+ * The maximum time `func` is allowed to be delayed before it's invoked.
140
+ * @param {boolean} [options.trailing=true]
141
+ * Specify invoking on the trailing edge of the timeout.
142
+ * @returns {Function} Returns the new debounced function.
143
+ * @example
144
+ *
145
+ * // Avoid costly calculations while the window size is in flux.
146
+ * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
147
+ *
148
+ * // Invoke `sendMail` when clicked, debouncing subsequent calls.
149
+ * jQuery(element).on('click', _.debounce(sendMail, 300, {
150
+ * 'leading': true,
151
+ * 'trailing': false
152
+ * }));
153
+ *
154
+ * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
155
+ * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
156
+ * var source = new EventSource('/stream');
157
+ * jQuery(source).on('message', debounced);
158
+ *
159
+ * // Cancel the trailing debounced invocation.
160
+ * jQuery(window).on('popstate', debounced.cancel);
161
+ */
162
+ function debounce(func, wait, options) {
163
+ var lastArgs,
164
+ lastThis,
165
+ maxWait,
166
+ result,
167
+ timerId,
168
+ lastCallTime,
169
+ lastInvokeTime = 0,
170
+ leading = false,
171
+ maxing = false,
172
+ trailing = true;
173
+
174
+ if (typeof func != 'function') {
175
+ throw new TypeError(FUNC_ERROR_TEXT);
176
+ }
177
+ wait = toNumber(wait) || 0;
178
+ if (isObject(options)) {
179
+ leading = !!options.leading;
180
+ maxing = 'maxWait' in options;
181
+ maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
182
+ trailing = 'trailing' in options ? !!options.trailing : trailing;
183
+ }
184
+
185
+ function invokeFunc(time) {
186
+ var args = lastArgs,
187
+ thisArg = lastThis;
188
+
189
+ lastArgs = lastThis = undefined;
190
+ lastInvokeTime = time;
191
+ result = func.apply(thisArg, args);
192
+ return result;
193
+ }
194
+
195
+ function leadingEdge(time) {
196
+ // Reset any `maxWait` timer.
197
+ lastInvokeTime = time;
198
+ // Start the timer for the trailing edge.
199
+ timerId = setTimeout(timerExpired, wait);
200
+ // Invoke the leading edge.
201
+ return leading ? invokeFunc(time) : result;
202
+ }
203
+
204
+ function remainingWait(time) {
205
+ var timeSinceLastCall = time - lastCallTime,
206
+ timeSinceLastInvoke = time - lastInvokeTime,
207
+ result = wait - timeSinceLastCall;
208
+
209
+ return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
210
+ }
211
+
212
+ function shouldInvoke(time) {
213
+ var timeSinceLastCall = time - lastCallTime,
214
+ timeSinceLastInvoke = time - lastInvokeTime;
215
+
216
+ // Either this is the first call, activity has stopped and we're at the
217
+ // trailing edge, the system time has gone backwards and we're treating
218
+ // it as the trailing edge, or we've hit the `maxWait` limit.
219
+ return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
220
+ (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
221
+ }
222
+
223
+ function timerExpired() {
224
+ var time = now();
225
+ if (shouldInvoke(time)) {
226
+ return trailingEdge(time);
227
+ }
228
+ // Restart the timer.
229
+ timerId = setTimeout(timerExpired, remainingWait(time));
230
+ }
231
+
232
+ function trailingEdge(time) {
233
+ timerId = undefined;
234
+
235
+ // Only invoke if we have `lastArgs` which means `func` has been
236
+ // debounced at least once.
237
+ if (trailing && lastArgs) {
238
+ return invokeFunc(time);
239
+ }
240
+ lastArgs = lastThis = undefined;
241
+ return result;
242
+ }
243
+
244
+ function cancel() {
245
+ if (timerId !== undefined) {
246
+ clearTimeout(timerId);
247
+ }
248
+ lastInvokeTime = 0;
249
+ lastArgs = lastCallTime = lastThis = timerId = undefined;
250
+ }
251
+
252
+ function flush() {
253
+ return timerId === undefined ? result : trailingEdge(now());
254
+ }
255
+
256
+ function debounced() {
257
+ var time = now(),
258
+ isInvoking = shouldInvoke(time);
259
+
260
+ lastArgs = arguments;
261
+ lastThis = this;
262
+ lastCallTime = time;
263
+
264
+ if (isInvoking) {
265
+ if (timerId === undefined) {
266
+ return leadingEdge(lastCallTime);
267
+ }
268
+ if (maxing) {
269
+ // Handle invocations in a tight loop.
270
+ timerId = setTimeout(timerExpired, wait);
271
+ return invokeFunc(lastCallTime);
272
+ }
273
+ }
274
+ if (timerId === undefined) {
275
+ timerId = setTimeout(timerExpired, wait);
276
+ }
277
+ return result;
278
+ }
279
+ debounced.cancel = cancel;
280
+ debounced.flush = flush;
281
+ return debounced;
282
+ }
72
283
 
73
- /** Used as a reference to the global object. */
74
- freeGlobal || freeSelf || Function('return this')();
284
+ /**
285
+ * Checks if `value` is the
286
+ * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
287
+ * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
288
+ *
289
+ * @static
290
+ * @memberOf _
291
+ * @since 0.1.0
292
+ * @category Lang
293
+ * @param {*} value The value to check.
294
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
295
+ * @example
296
+ *
297
+ * _.isObject({});
298
+ * // => true
299
+ *
300
+ * _.isObject([1, 2, 3]);
301
+ * // => true
302
+ *
303
+ * _.isObject(_.noop);
304
+ * // => true
305
+ *
306
+ * _.isObject(null);
307
+ * // => false
308
+ */
309
+ function isObject(value) {
310
+ var type = typeof value;
311
+ return !!value && (type == 'object' || type == 'function');
312
+ }
313
+
314
+ /**
315
+ * Checks if `value` is object-like. A value is object-like if it's not `null`
316
+ * and has a `typeof` result of "object".
317
+ *
318
+ * @static
319
+ * @memberOf _
320
+ * @since 4.0.0
321
+ * @category Lang
322
+ * @param {*} value The value to check.
323
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
324
+ * @example
325
+ *
326
+ * _.isObjectLike({});
327
+ * // => true
328
+ *
329
+ * _.isObjectLike([1, 2, 3]);
330
+ * // => true
331
+ *
332
+ * _.isObjectLike(_.noop);
333
+ * // => false
334
+ *
335
+ * _.isObjectLike(null);
336
+ * // => false
337
+ */
338
+ function isObjectLike(value) {
339
+ return !!value && typeof value == 'object';
340
+ }
341
+
342
+ /**
343
+ * Checks if `value` is classified as a `Symbol` primitive or object.
344
+ *
345
+ * @static
346
+ * @memberOf _
347
+ * @since 4.0.0
348
+ * @category Lang
349
+ * @param {*} value The value to check.
350
+ * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
351
+ * @example
352
+ *
353
+ * _.isSymbol(Symbol.iterator);
354
+ * // => true
355
+ *
356
+ * _.isSymbol('abc');
357
+ * // => false
358
+ */
359
+ function isSymbol(value) {
360
+ return typeof value == 'symbol' ||
361
+ (isObjectLike(value) && objectToString.call(value) == symbolTag);
362
+ }
363
+
364
+ /**
365
+ * Converts `value` to a number.
366
+ *
367
+ * @static
368
+ * @memberOf _
369
+ * @since 4.0.0
370
+ * @category Lang
371
+ * @param {*} value The value to process.
372
+ * @returns {number} Returns the number.
373
+ * @example
374
+ *
375
+ * _.toNumber(3.2);
376
+ * // => 3.2
377
+ *
378
+ * _.toNumber(Number.MIN_VALUE);
379
+ * // => 5e-324
380
+ *
381
+ * _.toNumber(Infinity);
382
+ * // => Infinity
383
+ *
384
+ * _.toNumber('3.2');
385
+ * // => 3.2
386
+ */
387
+ function toNumber(value) {
388
+ if (typeof value == 'number') {
389
+ return value;
390
+ }
391
+ if (isSymbol(value)) {
392
+ return NAN;
393
+ }
394
+ if (isObject(value)) {
395
+ var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
396
+ value = isObject(other) ? (other + '') : other;
397
+ }
398
+ if (typeof value != 'string') {
399
+ return value === 0 ? value : +value;
400
+ }
401
+ value = value.replace(reTrim, '');
402
+ var isBinary = reIsBinary.test(value);
403
+ return (isBinary || reIsOctal.test(value))
404
+ ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
405
+ : (reIsBadHex.test(value) ? NAN : +value);
406
+ }
407
+
408
+ lodash_debounce = debounce;
409
+ return lodash_debounce;
410
+ }
411
+
412
+ requireLodash_debounce();
75
413
 
76
414
  var useIsomorphicLayoutEffect$1 = typeof window !== "undefined" ? React.useLayoutEffect : React.useEffect;
77
415
  function useInterval(callback, delay) {
@@ -188,7 +526,8 @@ const GridContext = React.createContext({
188
526
  cancelEdit: () => {
189
527
  console.error('no context provider for cancelEdit');
190
528
  },
191
- startCellEditing: () => {
529
+ // eslint-disable-next-line @typescript-eslint/require-await
530
+ startCellEditing: async () => {
192
531
  console.error('no context provider for startCellEditing');
193
532
  },
194
533
  stopEditing: () => {
@@ -303,6 +642,38 @@ const sanitiseFileName = (filename) => {
303
642
  return valid.slice(0, -fileExt.length - 1).slice(0, 64) + '.' + fileExt;
304
643
  };
305
644
 
645
+ /**
646
+ * AgGrid checkbox select does not pass clicks within cell but not on the checkbox to checkbox.
647
+ * This passes the event to the checkbox when you click anywhere in the cell.
648
+ */
649
+ const clickInputWhenContainingCellClicked = (params) => {
650
+ const { data, event, colDef } = params;
651
+ if (!data || !event)
652
+ return;
653
+ const element = event.target;
654
+ // Already handled
655
+ if (element.closest('.GridCell-readonly') ||
656
+ (['BUTTON', 'INPUT'].includes(element?.tagName) && element.closest('.ag-cell-inline-editing'))) {
657
+ return;
658
+ }
659
+ const row = element.closest('[row-id]');
660
+ if (!row)
661
+ return;
662
+ const colId = colDef.colId;
663
+ if (!colId)
664
+ return;
665
+ const clickInput = () => {
666
+ const cell = row.querySelector(`[col-id='${colId}']`);
667
+ if (!cell)
668
+ return;
669
+ const input = cell.querySelector('input, button');
670
+ if (!input)
671
+ return;
672
+ input?.dispatchEvent(event);
673
+ };
674
+ setTimeout(clickInput, 20);
675
+ };
676
+
306
677
  /**
307
678
  * AgGrid's existing select header doesn't work the way we want.
308
679
  * If you have partial select then clicking the header checkbox will select all,
@@ -323,7 +694,7 @@ const GridHeaderSelect = ({ api }) => {
323
694
  }, [api, updateCounter]);
324
695
  const handleMultiSelect = () => {
325
696
  if (selectedNodeCount == 0) {
326
- api.selectAllFiltered();
697
+ api.selectAll('filtered');
327
698
  }
328
699
  else {
329
700
  api.deselectAll();
@@ -812,7 +1183,6 @@ const useTransitionState = ({
812
1183
  enterStage && transitState(exit ? preExit ? PRE_EXIT : EXITING : startOrEnd(unmountOnExit));
813
1184
  }
814
1185
  }, [endTransition, onChange, enter, exit, preEnter, preExit, enterTimeout, exitTimeout, unmountOnExit]);
815
- React.useEffect(() => () => clearTimeout(timeoutId.current), []);
816
1186
  return [state, toggle, endTransition];
817
1187
  };
818
1188
 
@@ -1627,15 +1997,23 @@ const ControlledMenuFr = ({ 'aria-label': ariaLabel, className, containerProps,
1627
1997
  const handleKeyboardTabAndEnter = React.useCallback((isDown) => (ev) => {
1628
1998
  const thisDocument = anchorRef?.current ? anchorRef?.current.ownerDocument : document;
1629
1999
  const activeElement = thisDocument.activeElement;
1630
- if (!anchorRef?.current || !activeElement)
2000
+ if (!anchorRef?.current || !activeElement) {
1631
2001
  return;
1632
- if (ev.key !== 'Tab' && ev.key !== 'Enter')
2002
+ }
2003
+ if (ev.key !== 'Tab' && ev.key !== 'Enter' && ev.key !== 'Esc') {
1633
2004
  return;
2005
+ }
1634
2006
  if (ev.repeat) {
1635
2007
  ev.preventDefault();
1636
2008
  ev.stopPropagation();
1637
2009
  return;
1638
2010
  }
2011
+ if (ev.key === 'Esc') {
2012
+ ev.preventDefault();
2013
+ ev.stopPropagation();
2014
+ safeCall(onClose, { key: ev.key, reason: CloseReason.CANCEL });
2015
+ return;
2016
+ }
1639
2017
  const invokeSave = (reason) => {
1640
2018
  if (!saveButtonRef?.current)
1641
2019
  return;
@@ -1751,6 +2129,7 @@ const ControlledMenuFr = ({ 'aria-label': ariaLabel, className, containerProps,
1751
2129
  },
1752
2130
  }), [onItemClick, onClose]);
1753
2131
  const onKeyUp = (e) => {
2132
+ console.log(e);
1754
2133
  switch (e.key) {
1755
2134
  case Keys.ESC:
1756
2135
  e.preventDefault();
@@ -1782,7 +2161,7 @@ const ControlledMenuFr = ({ 'aria-label': ariaLabel, className, containerProps,
1782
2161
  block: menuContainerClass,
1783
2162
  modifiers,
1784
2163
  className,
1785
- }), style: { ...containerProps?.style, position: 'relative' }, ref: containerRef, children: state && (jsxRuntime.jsx(SettingsContext.Provider, { value: settings, children: jsxRuntime.jsx(ItemSettingsContext.Provider, { value: itemSettings, children: jsxRuntime.jsx(EventHandlersContext.Provider, { value: eventHandlers, children: jsxRuntime.jsx(MenuList, { ...restProps, ariaLabel: ariaLabel || 'Menu', externalRef: externalRef, containerRef: containerRef, onClose: onClose }) }) }) })) }));
2164
+ }), style: { ...containerProps?.style, position: 'relative' }, ref: containerRef, children: state && (jsxRuntime.jsx(SettingsContext.Provider, { value: settings, children: jsxRuntime.jsx(ItemSettingsContext.Provider, { value: itemSettings, children: jsxRuntime.jsx(EventHandlersContext.Provider, { value: eventHandlers, children: jsxRuntime.jsx(MenuList, { ...restProps, ariaLabel: ariaLabel || 'Menu', externalRef: externalRef, containerRef: containerRef, onClose: onClose, onBlur: () => console.log('blur') }) }) }) })) }));
1786
2165
  if (portal === true && anchorRef?.current != null) {
1787
2166
  if (hasParentClass('react-menu-inline-test', anchorRef.current)) {
1788
2167
  portal = false;
@@ -2374,12 +2753,14 @@ const usePostSortRowsHook = ({ setStaleGrid }) => {
2374
2753
  }, [redrawRows, setStaleGrid]);
2375
2754
  };
2376
2755
 
2756
+ agGridCommunity.ModuleRegistry.registerModules([agGridCommunity.AllCommunityModule]);
2377
2757
  /**
2378
2758
  * Wrapper for AgGrid to add commonly used functionality.
2379
2759
  */
2380
- const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection = 'multiple', suppressColumnVirtualization = true, theme = 'ag-theme-step-default', sizeColumns = 'auto', selectColumnPinned = null, contextMenuSelectRow = false, singleClickEdit = false, rowData, rowHeight = theme === 'ag-theme-step-default' ? 40 : theme === 'ag-theme-step-compact' ? 36 : 40, ...params }) => {
2760
+ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection = 'multiple', suppressColumnVirtualization = true, theme = 'ag-theme-step-default', sizeColumns = 'auto', selectColumnPinned = 'left', contextMenuSelectRow = false, singleClickEdit = false, rowData, rowHeight = theme === 'ag-theme-step-default' ? 40 : theme === 'ag-theme-step-compact' ? 36 : 40, selectable, ...params }) => {
2381
2761
  const { gridReady, gridRenderState, setApis, ensureRowVisible, getFirstRowId, selectRowsById, focusByRowById, ensureSelectedRowIsVisible, autoSizeColumns, sizeColumnsToFit, externallySelectedItemsAreInSync, setExternallySelectedItemsAreInSync, isExternalFilterPresent, doesExternalFilterPass, setOnCellEditingComplete, getColDef, showNoRowsOverlay, prePopupOps, stopEditing, } = React.useContext(GridContext);
2382
- const { checkUpdating, updatedDep, updatingCols } = React.useContext(GridUpdatingContext);
2762
+ const { startCellEditing } = useGridContext();
2763
+ const { updatedDep, updatingCols } = React.useContext(GridUpdatingContext);
2383
2764
  const gridDivRef = React.useRef(null);
2384
2765
  const lastSelectedIds = React.useRef([]);
2385
2766
  const [staleGrid, setStaleGrid] = React.useState(false);
@@ -2545,7 +2926,7 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
2545
2926
  * Add selectable column to colDefs. Adjust column defs to block fit for auto sized columns.
2546
2927
  */
2547
2928
  const columnDefs = React.useMemo(() => {
2548
- const adjustColDefs = params.columnDefs.map((colDef) => {
2929
+ return params.columnDefs.map((colDef) => {
2549
2930
  const colDefEditable = colDef.editable;
2550
2931
  const editable = combineEditables(params.loading !== true && params.readOnly !== true, params.defaultColDef?.editable, colDefEditable);
2551
2932
  return {
@@ -2557,50 +2938,7 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
2557
2938
  },
2558
2939
  };
2559
2940
  });
2560
- return params.selectable || params.onRowDragEnd
2561
- ? [
2562
- {
2563
- colId: 'selection',
2564
- editable: false,
2565
- rowDrag: !!params.onRowDragEnd,
2566
- minWidth: params.selectable && params.onRowDragEnd ? 76 : 48,
2567
- maxWidth: params.selectable && params.onRowDragEnd ? 76 : 48,
2568
- pinned: selectColumnPinned,
2569
- headerComponentParams: {
2570
- exportable: false,
2571
- },
2572
- checkboxSelection: params.selectable,
2573
- headerClass: params.onRowDragEnd ? 'ag-header-select-draggable' : undefined,
2574
- headerComponent: rowSelection === 'multiple' ? GridHeaderSelect : null,
2575
- suppressHeaderKeyboardEvent: (e) => {
2576
- if (!params.selectable)
2577
- return false;
2578
- if ((e.event.key === 'Enter' || e.event.key === ' ') && !e.event.repeat) {
2579
- if (lodashEs.isEmpty(e.api.getSelectedRows())) {
2580
- e.api.selectAllFiltered();
2581
- }
2582
- else {
2583
- e.api.deselectAll();
2584
- }
2585
- return true;
2586
- }
2587
- return false;
2588
- },
2589
- onCellClicked: clickInputWhenContainingCellClicked,
2590
- },
2591
- ...adjustColDefs,
2592
- ]
2593
- : adjustColDefs;
2594
- }, [
2595
- params.columnDefs,
2596
- params.selectable,
2597
- params.onRowDragEnd,
2598
- params.loading,
2599
- params.readOnly,
2600
- params.defaultColDef?.editable,
2601
- selectColumnPinned,
2602
- rowSelection,
2603
- ]);
2941
+ }, [params.columnDefs, params.loading, params.readOnly, params.defaultColDef?.editable]);
2604
2942
  /**
2605
2943
  * When grid is ready set the apis to the grid context and sync selected items to grid.
2606
2944
  */
@@ -2641,44 +2979,28 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
2641
2979
  /**
2642
2980
  * Force-refresh all selected rows to re-run class function, to update selection highlighting
2643
2981
  */
2644
- const refreshSelectedRows = React.useCallback((event) => {
2645
- event.api.refreshCells({
2646
- force: true,
2647
- rowNodes: event.api.getSelectedNodes(),
2648
- });
2982
+ const refreshSelectedRows = React.useCallback((_event) => {
2983
+ // MATT Disabled I don't believe these are needed anymore
2984
+ // I've left them here just in case they are
2985
+ /*event.api.refreshCells({
2986
+ force: true,
2987
+ rowNodes: event.api.getSelectedNodes(),
2988
+ });*/
2649
2989
  }, []);
2650
- /**
2651
- * Make sure node is selected for editing and start edit
2652
- */
2653
- const startCellEditing = React.useCallback((event) => {
2654
- prePopupOps();
2655
- if (!event.node.isSelected()) {
2656
- event.node.setSelected(true, true);
2657
- }
2658
- // Cell already being edited, so don't re-edit until finished
2659
- if (checkUpdating([event.colDef.field ?? ''], event.data.id)) {
2660
- return;
2661
- }
2662
- if (event.rowIndex !== null) {
2663
- event.api.startEditingCell({
2664
- rowIndex: event.rowIndex,
2665
- colKey: event.column.getColId(),
2666
- });
2667
- }
2668
- }, [checkUpdating, prePopupOps]);
2669
2990
  /**
2670
2991
  * Handle double click edit
2671
2992
  */
2672
2993
  const onCellDoubleClick = React.useCallback((event) => {
2673
- if (!invokeEditAction(event))
2674
- startCellEditing(event);
2994
+ if (!invokeEditAction(event)) {
2995
+ void startCellEditing({ rowId: event.data.id, colId: event.column.getColId() });
2996
+ }
2675
2997
  }, [startCellEditing]);
2676
2998
  /**
2677
2999
  * Handle single click edits
2678
3000
  */
2679
3001
  const onCellClicked = React.useCallback((event) => {
2680
3002
  if (event.colDef?.cellRendererParams?.singleClickEdit ?? singleClickEdit) {
2681
- startCellEditing(event);
3003
+ void startCellEditing({ rowId: event.data.id, colId: event.column.getColId() });
2682
3004
  }
2683
3005
  }, [singleClickEdit, startCellEditing]);
2684
3006
  /**
@@ -2703,11 +3025,11 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
2703
3025
  const onCellKeyPress = React.useCallback((e) => {
2704
3026
  const kbe = e.event;
2705
3027
  if (kbe.key === 'Enter') {
2706
- if (!invokeEditAction(e))
2707
- startCellEditing(e);
3028
+ if (!invokeEditAction(e)) {
3029
+ void startCellEditing({ rowId: e.data.id, colId: e.column.getColId() });
3030
+ }
2708
3031
  }
2709
3032
  if (kbe.key === 'Tab') {
2710
- // eslint-disable-next-line
2711
3033
  prePopupOps();
2712
3034
  }
2713
3035
  }, [prePopupOps, startCellEditing]);
@@ -2807,55 +3129,93 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
2807
3129
  }
2808
3130
  }, []);
2809
3131
  const gridContextMenu = useGridContextMenu({ contextMenu: params.contextMenu, contextMenuSelectRow });
2810
- const onRowDragLeave = React.useCallback((event) => {
2811
- const clientSideRowModel = event.api.getModel();
2812
- clientSideRowModel.highlightRowAtPixel(null);
3132
+ const startDragYRef = React.useRef(null);
3133
+ const clearHighlightRowClasses = React.useCallback(() => {
3134
+ document.querySelectorAll(`.ag-row-highlight-above`)?.forEach((el) => {
3135
+ el.classList.remove('ag-row-highlight-above');
3136
+ });
3137
+ document.querySelectorAll(`.ag-row-highlight-below`)?.forEach((el) => {
3138
+ el.classList.remove('ag-row-highlight-below');
3139
+ });
2813
3140
  }, []);
3141
+ const gridElementRef = React.useRef();
2814
3142
  const onRowDragMove = React.useCallback((event) => {
2815
- if (event.overNode && event.node.rowIndex != null) {
2816
- const clientSideRowModel = event.api.getModel();
2817
- //position 0 means highlight above, 1 means below
2818
- const position = clientSideRowModel.getHighlightPosition(event.y, event.overNode);
2819
- //we don't want to show the row highlight if it wouldn't result in the row moving
2820
- const targetIndex = event.overIndex + position - (event.node.rowIndex < event.overIndex ? 1 : 0);
2821
- if (event.node.rowIndex != targetIndex) {
2822
- clientSideRowModel.highlightRowAtPixel(event.node, event.y);
3143
+ if (startDragYRef.current === null) {
3144
+ startDragYRef.current = event.y;
3145
+ }
3146
+ const yDiff = event.y - startDragYRef.current;
3147
+ const data = event.overNode?.data;
3148
+ if (data) {
3149
+ clearHighlightRowClasses();
3150
+ // Find the grid element, this can only be found on start drag.
3151
+ // Once dragging is no progress the event target is the drag element not the start drag column.
3152
+ const targetEl = event.event.target;
3153
+ if (targetEl) {
3154
+ const gridElement = targetEl.closest('.ag-body');
3155
+ if (gridElement) {
3156
+ gridElementRef.current = gridElement;
3157
+ }
2823
3158
  }
3159
+ gridElementRef.current?.querySelectorAll(`[row-id='${data.id}']`)?.forEach((el) => {
3160
+ el.classList.add(yDiff < 0 ? 'ag-row-highlight-above' : 'ag-row-highlight-below');
3161
+ });
2824
3162
  }
2825
- }, []);
3163
+ }, [clearHighlightRowClasses]);
2826
3164
  const onRowDragEnd = React.useCallback((event) => {
2827
- void (async () => {
2828
- const clientSideRowModel = event.api.getModel();
2829
- if (event.node.rowIndex != null) {
2830
- const lastHighlightedRowNode = clientSideRowModel.getLastHighlightedRowNode();
2831
- const isBelow = lastHighlightedRowNode && lastHighlightedRowNode.highlighted === agGridCommunity.RowHighlightPosition.Below;
2832
- let targetIndex = event.overIndex;
2833
- if (event.node.rowIndex > event.overIndex) {
2834
- targetIndex += isBelow ? 1 : 0;
2835
- }
2836
- else {
2837
- targetIndex += isBelow ? 0 : -1;
2838
- }
2839
- const moved = event.node.data;
2840
- const target = event.overNode?.data;
2841
- moved.id !== target?.id && //moved over a different row
2842
- event.node.rowIndex != targetIndex && //moved to a different index
2843
- params.onRowDragEnd &&
2844
- (await params.onRowDragEnd(moved, target, targetIndex));
3165
+ clearHighlightRowClasses();
3166
+ gridElementRef.current = undefined;
3167
+ if (!params.onRowDragEnd || startDragYRef.current === null) {
3168
+ return;
3169
+ }
3170
+ const yDiff = event.y - startDragYRef.current;
3171
+ startDragYRef.current = null;
3172
+ if (event.node.rowIndex != null) {
3173
+ const movedRow = event.node.data;
3174
+ const targetRow = event.overNode?.data;
3175
+ if (!movedRow || !targetRow || movedRow === targetRow || yDiff === 0) {
3176
+ return;
2845
3177
  }
2846
- clientSideRowModel.highlightRowAtPixel(null);
2847
- })();
2848
- }, [params]);
3178
+ void params.onRowDragEnd({ movedRow, targetRow, direction: yDiff > 0 ? 1 : -1 });
3179
+ }
3180
+ }, [params, clearHighlightRowClasses]);
2849
3181
  // This is setting a ref in the GridContext so won't be triggering an update loop
2850
3182
  setOnCellEditingComplete(params.onCellEditingComplete);
2851
3183
  const headerRowCount = columnDefs.some((c) => c.children) ? 2 : 1;
2852
- return (jsxRuntime.jsxs("div", { "data-testid": dataTestId, className: clsx('Grid-container', theme, 'theme-specific', staleGrid && 'Grid-sortIsStale', gridReady && rowData && autoSized && 'Grid-ready'), children: [gridContextMenu.component, jsxRuntime.jsx("div", { style: { flex: 1 }, ref: gridDivRef, children: jsxRuntime.jsx(agGridReact.AgGridReact, { rowHeight: rowHeight, animateRows: params.animateRows ?? false, rowClassRules: params.rowClassRules, getRowId: (params) => `${params.data.id}`, suppressRowClickSelection: true, rowSelection: rowSelection, suppressBrowserResizeObserver: true, onGridSizeChanged: onGridSizeChanged, suppressColumnVirtualisation: suppressColumnVirtualization, suppressClickEdit: true, onColumnVisible: () => {
2853
- setInitialContentSize();
2854
- }, onRowDataUpdated: onRowDataChanged, onCellKeyDown: onCellKeyPress, onCellClicked: onCellClicked, onCellDoubleClicked: onCellDoubleClick, onCellEditingStarted: refreshSelectedRows, domLayout: params.domLayout, onColumnResized: onColumnResized, defaultColDef: { minWidth: 48, ...lodashEs.omit(params.defaultColDef, ['editable']) }, columnDefs: columnDefsAdjusted, rowData: rowData, noRowsOverlayComponent: (event) => {
3184
+ return (jsxRuntime.jsxs("div", { "data-testid": dataTestId, className: clsx('Grid-container', theme, 'theme-specific', staleGrid && 'Grid-sortIsStale', gridReady && rowData && autoSized && 'Grid-ready'), children: [gridContextMenu.component, jsxRuntime.jsx("div", { style: { flex: 1 }, ref: gridDivRef, children: jsxRuntime.jsx(agGridReact.AgGridReact, { theme: 'legacy', rowSelection: selectable
3185
+ ? {
3186
+ enableClickSelection: false,
3187
+ mode: rowSelection == 'single' ? 'singleRow' : 'multiRow',
3188
+ }
3189
+ : undefined, rowHeight: rowHeight, animateRows: params.animateRows ?? false, rowClassRules: params.rowClassRules, getRowId: (params) => `${params.data.id}`, onGridSizeChanged: onGridSizeChanged, suppressColumnVirtualisation: suppressColumnVirtualization, suppressClickEdit: true, onColumnVisible: setInitialContentSize, onRowDataUpdated: onRowDataChanged, onCellKeyDown: onCellKeyPress, onCellClicked: onCellClicked, onCellDoubleClicked: onCellDoubleClick, onCellEditingStarted: refreshSelectedRows, domLayout: params.domLayout, onColumnResized: onColumnResized, defaultColDef: { minWidth: 48, ...lodashEs.omit(params.defaultColDef, ['editable']) }, columnDefs: columnDefsAdjusted, rowData: rowData, noRowsOverlayComponent: (event) => {
2855
3190
  let rowCount = 0;
2856
3191
  event.api.forEachNode(() => rowCount++);
2857
3192
  return (jsxRuntime.jsx(GridNoRowsOverlay, { loading: !rowData || params.loading === true, rowCount: rowCount, headerRowHeight: headerRowCount * rowHeight, filteredRowCount: event.api.getDisplayedRowCount(), noRowsOverlayText: params.noRowsOverlayText, noRowsMatchingOverlayText: params.noRowsMatchingOverlayText }));
2858
- }, onModelUpdated: onModelUpdated, onGridReady: onGridReady, onSortChanged: ensureSelectedRowIsVisible, postSortRows: params.onRowDragEnd || !defaultPostSort ? undefined : postSortRows, onSelectionChanged: synchroniseExternalStateToGridSelection, onColumnMoved: params.onColumnMoved, alwaysShowVerticalScroll: params.alwaysShowVerticalScroll, isExternalFilterPresent: isExternalFilterPresent, doesExternalFilterPass: doesExternalFilterPass, maintainColumnOrder: true, preventDefaultOnContextMenu: true, onCellContextMenu: gridContextMenu.cellContextMenu, rowDragText: params.rowDragText, onRowDragMove: onRowDragMove, onRowDragEnd: onRowDragEnd, onRowDragLeave: onRowDragLeave, suppressCellFocus: params.suppressCellFocus, pinnedTopRowData: params.pinnedTopRowData, pinnedBottomRowData: params.pinnedBottomRowData }) })] }));
3193
+ }, onModelUpdated: onModelUpdated, onGridReady: onGridReady, onSortChanged: ensureSelectedRowIsVisible, postSortRows: params.onRowDragEnd || !defaultPostSort ? undefined : postSortRows, onSelectionChanged: synchroniseExternalStateToGridSelection, onColumnMoved: params.onColumnMoved, alwaysShowVerticalScroll: params.alwaysShowVerticalScroll, isExternalFilterPresent: isExternalFilterPresent, doesExternalFilterPass: doesExternalFilterPass, maintainColumnOrder: true, preventDefaultOnContextMenu: true, onCellContextMenu: gridContextMenu.cellContextMenu, rowDragText: params.rowDragText, onRowDragCancel: clearHighlightRowClasses, onRowDragMove: onRowDragMove, onRowDragEnd: onRowDragEnd, suppressCellFocus: params.suppressCellFocus, pinnedTopRowData: params.pinnedTopRowData, pinnedBottomRowData: params.pinnedBottomRowData, selectionColumnDef: {
3194
+ rowDrag: !!params.onRowDragEnd,
3195
+ minWidth: selectable && params.onRowDragEnd ? 76 : 48,
3196
+ maxWidth: selectable && params.onRowDragEnd ? 76 : 48,
3197
+ pinned: selectColumnPinned,
3198
+ headerComponentParams: {
3199
+ exportable: false,
3200
+ },
3201
+ headerClass: clsx('ag-header-hide-default-select', params.onRowDragEnd && 'ag-header-select-draggable'),
3202
+ headerComponent: rowSelection == 'multiple' ? GridHeaderSelect : undefined,
3203
+ suppressHeaderKeyboardEvent: (e) => {
3204
+ if (!selectable)
3205
+ return false;
3206
+ if ((e.event.key === 'Enter' || e.event.key === ' ') && !e.event.repeat) {
3207
+ if (lodashEs.isEmpty(e.api.getSelectedRows())) {
3208
+ e.api.selectAll('filtered');
3209
+ }
3210
+ else {
3211
+ e.api.deselectAll();
3212
+ }
3213
+ return true;
3214
+ }
3215
+ return false;
3216
+ },
3217
+ onCellClicked: clickInputWhenContainingCellClicked,
3218
+ } }) })] }));
2859
3219
  };
2860
3220
 
2861
3221
  const GridPopoverContext = React.createContext({
@@ -3245,79 +3605,89 @@ const GridFilterQuick = ({ quickFilterPlaceholder, defaultValue }) => {
3245
3605
 
3246
3606
  const GridFilters = ({ children }) => (jsxRuntime.jsx("div", { className: "Grid-container-filters", children: children }));
3247
3607
 
3248
- /* global setTimeout, clearTimeout */
3608
+ var dist;
3609
+ var hasRequiredDist;
3249
3610
 
3250
- var dist = function debounce(fn) {
3251
- var wait = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
3252
- var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
3611
+ function requireDist () {
3612
+ if (hasRequiredDist) return dist;
3613
+ hasRequiredDist = 1;
3253
3614
 
3254
- var lastCallAt = undefined;
3255
- var deferred = undefined;
3256
- var timer = undefined;
3257
- var pendingArgs = [];
3258
- return function debounced() {
3259
- var currentWait = getWait(wait);
3260
- var currentTime = new Date().getTime();
3615
+ /* global setTimeout, clearTimeout */
3261
3616
 
3262
- var isCold = !lastCallAt || currentTime - lastCallAt > currentWait;
3617
+ dist = function debounce(fn) {
3618
+ var wait = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
3619
+ var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
3263
3620
 
3264
- lastCallAt = currentTime;
3621
+ var lastCallAt = void 0;
3622
+ var deferred = void 0;
3623
+ var timer = void 0;
3624
+ var pendingArgs = [];
3625
+ return function debounced() {
3626
+ var currentWait = getWait(wait);
3627
+ var currentTime = new Date().getTime();
3265
3628
 
3266
- for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
3267
- args[_key] = arguments[_key];
3268
- }
3629
+ var isCold = !lastCallAt || currentTime - lastCallAt > currentWait;
3269
3630
 
3270
- if (isCold && options.leading) {
3271
- return options.accumulate ? Promise.resolve(fn.call(this, [args])).then(function (result) {
3272
- return result[0];
3273
- }) : Promise.resolve(fn.call.apply(fn, [this].concat(args)));
3274
- }
3631
+ lastCallAt = currentTime;
3275
3632
 
3276
- if (deferred) {
3277
- clearTimeout(timer);
3278
- } else {
3279
- deferred = defer();
3280
- }
3633
+ for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
3634
+ args[_key] = arguments[_key];
3635
+ }
3281
3636
 
3282
- pendingArgs.push(args);
3283
- timer = setTimeout(flush.bind(this), currentWait);
3637
+ if (isCold && options.leading) {
3638
+ return options.accumulate ? Promise.resolve(fn.call(this, [args])).then(function (result) {
3639
+ return result[0];
3640
+ }) : Promise.resolve(fn.call.apply(fn, [this].concat(args)));
3641
+ }
3284
3642
 
3285
- if (options.accumulate) {
3286
- var argsIndex = pendingArgs.length - 1;
3287
- return deferred.promise.then(function (results) {
3288
- return results[argsIndex];
3289
- });
3290
- }
3643
+ if (deferred) {
3644
+ clearTimeout(timer);
3645
+ } else {
3646
+ deferred = defer();
3647
+ }
3291
3648
 
3292
- return deferred.promise;
3293
- };
3649
+ pendingArgs.push(args);
3650
+ timer = setTimeout(flush.bind(this), currentWait);
3294
3651
 
3295
- function flush() {
3296
- var thisDeferred = deferred;
3297
- clearTimeout(timer);
3652
+ if (options.accumulate) {
3653
+ var argsIndex = pendingArgs.length - 1;
3654
+ return deferred.promise.then(function (results) {
3655
+ return results[argsIndex];
3656
+ });
3657
+ }
3298
3658
 
3299
- Promise.resolve(options.accumulate ? fn.call(this, pendingArgs) : fn.apply(this, pendingArgs[pendingArgs.length - 1])).then(thisDeferred.resolve, thisDeferred.reject);
3659
+ return deferred.promise;
3660
+ };
3300
3661
 
3301
- pendingArgs = [];
3302
- deferred = null;
3303
- }
3304
- };
3662
+ function flush() {
3663
+ var thisDeferred = deferred;
3664
+ clearTimeout(timer);
3305
3665
 
3306
- function getWait(wait) {
3307
- return typeof wait === 'function' ? wait() : wait;
3308
- }
3666
+ Promise.resolve(options.accumulate ? fn.call(this, pendingArgs) : fn.apply(this, pendingArgs[pendingArgs.length - 1])).then(thisDeferred.resolve, thisDeferred.reject);
3309
3667
 
3310
- function defer() {
3311
- var deferred = {};
3312
- deferred.promise = new Promise(function (resolve, reject) {
3313
- deferred.resolve = resolve;
3314
- deferred.reject = reject;
3315
- });
3316
- return deferred;
3317
- }
3668
+ pendingArgs = [];
3669
+ deferred = null;
3670
+ }
3671
+ };
3318
3672
 
3673
+ function getWait(wait) {
3674
+ return typeof wait === 'function' ? wait() : wait;
3675
+ }
3676
+
3677
+ function defer() {
3678
+ var deferred = {};
3679
+ deferred.promise = new Promise(function (resolve, reject) {
3680
+ deferred.resolve = resolve;
3681
+ deferred.reject = reject;
3682
+ });
3683
+ return deferred;
3684
+ }
3685
+
3686
+ return dist;
3687
+ }
3319
3688
 
3320
- var debounce = /*@__PURE__*/getDefaultExportFromCjs(dist);
3689
+ var distExports = requireDist();
3690
+ var debounce = /*@__PURE__*/getDefaultExportFromCjs(distExports);
3321
3691
 
3322
3692
  const GridSubComponentContext = React.createContext({
3323
3693
  value: 'GridSubComponentContext value no context',
@@ -3336,7 +3706,7 @@ const GridSubComponentContext = React.createContext({
3336
3706
  });
3337
3707
 
3338
3708
  function styleInject(css, ref) {
3339
- if ( ref === undefined ) ref = {};
3709
+ if ( ref === void 0 ) ref = {};
3340
3710
  var insertAt = ref.insertAt;
3341
3711
 
3342
3712
  if (!css || typeof document === 'undefined') { return; }
@@ -4703,10 +5073,10 @@ const GridContextProvider = (props) => {
4703
5073
  const ensureRowVisible = React.useCallback((id) => {
4704
5074
  if (!gridApi)
4705
5075
  return false;
4706
- const node = gridApi?.getRowNode(`${id}`);
5076
+ const node = gridApi.getRowNode(`${id}`);
4707
5077
  if (!node)
4708
5078
  return false;
4709
- lodashEs.defer(() => gridApi.ensureNodeVisible(node));
5079
+ lodashEs.defer(() => !gridApi.isDestroyed() && gridApi.ensureNodeVisible(node));
4710
5080
  return true;
4711
5081
  }, [gridApi]);
4712
5082
  const getFirstRowId = React.useCallback(() => {
@@ -4764,16 +5134,20 @@ const GridContextProvider = (props) => {
4764
5134
  * Before a popup record the currently focused cell.
4765
5135
  */
4766
5136
  const prePopupOps = React.useCallback(() => {
4767
- prePopupFocusedCell.current = gridApi?.getFocusedCell() ?? undefined;
5137
+ if (!gridApi || gridApi.isDestroyed()) {
5138
+ return;
5139
+ }
5140
+ prePopupFocusedCell.current = gridApi.getFocusedCell() ?? undefined;
4768
5141
  }, [gridApi]);
4769
5142
  /**
4770
5143
  * After a popup refocus the cell.
4771
5144
  */
4772
5145
  const postPopupOps = React.useCallback(() => {
4773
- if (!gridApi)
5146
+ if (!gridApi || gridApi.isDestroyed()) {
4774
5147
  return;
5148
+ }
4775
5149
  if (prePopupFocusedCell.current) {
4776
- gridApi?.setFocusedCell(prePopupFocusedCell.current.rowIndex, prePopupFocusedCell.current.column);
5150
+ gridApi.setFocusedCell(prePopupFocusedCell.current.rowIndex, prePopupFocusedCell.current.column);
4777
5151
  }
4778
5152
  }, [gridApi]);
4779
5153
  /**
@@ -4841,7 +5215,7 @@ const GridContextProvider = (props) => {
4841
5215
  const rowsThatNeedSelecting = lodashEs.sortBy(rowNodes.filter((node) => !node.isSelected()), (node) => node.data.id);
4842
5216
  const firstNode = rowsThatNeedSelecting[0];
4843
5217
  if (firstNode) {
4844
- lodashEs.defer(() => gridApi.ensureNodeVisible(firstNode));
5218
+ lodashEs.defer(() => !gridApi.isDestroyed() && gridApi.ensureNodeVisible(firstNode));
4845
5219
  const colDefs = getColumns();
4846
5220
  if (!lodashEs.isEmpty(colDefs)) {
4847
5221
  const col = colDefs[0];
@@ -4852,9 +5226,14 @@ const GridContextProvider = (props) => {
4852
5226
  // as they will start to edit the cell before this stuff has a chance to run
4853
5227
  colId &&
4854
5228
  lodashEs.delay(() => {
4855
- if (lodashEs.isEmpty(gridApi.getEditingCells()) && (!ifNoCellFocused || gridApi.getFocusedCell() == null)) {
4856
- // ifNoCellFocused
5229
+ if (lodashEs.isEmpty(gridApi.getEditingCells()) &&
5230
+ (!ifNoCellFocused || gridApi.getFocusedCell() == null) &&
5231
+ !gridApi.isDestroyed()) {
4857
5232
  gridApi.setFocusedCell(rowIndex, colId);
5233
+ // It may be that the first cell is the selection cell, this doesn't exist as a colDef
5234
+ // so instead, I just try and select it. If it doesn't exist selection will stay on the
5235
+ // previously focused cell
5236
+ gridApi.setFocusedCell(rowIndex, 'ag-Grid-SelectionColumn');
4858
5237
  }
4859
5238
  }, 100);
4860
5239
  }
@@ -4873,7 +5252,7 @@ const GridContextProvider = (props) => {
4873
5252
  if (flash) {
4874
5253
  lodashEs.delay(() => {
4875
5254
  try {
4876
- gridApi.flashCells({ rowNodes });
5255
+ !gridApi.isDestroyed && gridApi.flashCells({ rowNodes });
4877
5256
  }
4878
5257
  catch {
4879
5258
  // ignore, flash cells sometimes throws errors as nodes have gone out of scope
@@ -4927,7 +5306,7 @@ const GridContextProvider = (props) => {
4927
5306
  const selectedNodes = gridApi.getSelectedNodes();
4928
5307
  if (lodashEs.isEmpty(selectedNodes))
4929
5308
  return;
4930
- lodashEs.defer(() => gridApi.ensureNodeVisible(lodashEs.last(selectedNodes)));
5309
+ lodashEs.defer(() => !gridApi.isDestroyed() && gridApi.ensureNodeVisible(lodashEs.last(selectedNodes)));
4931
5310
  });
4932
5311
  }, [gridApiOp]);
4933
5312
  /**
@@ -4957,44 +5336,58 @@ const GridContextProvider = (props) => {
4957
5336
  gridApi?.sizeColumnsToFit();
4958
5337
  }, [gridApi]);
4959
5338
  const stopEditing = React.useCallback(() => {
4960
- if (!gridApi)
5339
+ if (!gridApi || gridApi.isDestroyed()) {
4961
5340
  return;
4962
- if (prePopupFocusedCell.current) {
4963
- gridApi?.setFocusedCell(prePopupFocusedCell.current.rowIndex, prePopupFocusedCell.current.column);
4964
5341
  }
4965
5342
  gridApi.stopEditing();
5343
+ if (prePopupFocusedCell.current) {
5344
+ gridApi.setFocusedCell(prePopupFocusedCell.current.rowIndex, prePopupFocusedCell.current.column);
5345
+ }
4966
5346
  }, [gridApi]);
4967
- const startCellEditing = React.useCallback(
4968
- // eslint-disable-next-line @typescript-eslint/require-await
4969
- ({ rowId, colId }) => {
5347
+ // waitForExternallySelectedItemsToBeInSync can't use the state as it won't be updated during function execution
5348
+ const externallySelectedItemsAreInSyncRef = React.useRef(false);
5349
+ React.useEffect(() => {
5350
+ externallySelectedItemsAreInSyncRef.current = externallySelectedItemsAreInSync;
5351
+ }, [externallySelectedItemsAreInSync]);
5352
+ const waitForExternallySelectedItemsToBeInSync = React.useCallback(async () => {
5353
+ // Wait for up to 5 seconds
5354
+ for (let i = 0; i < 5000 / 200 && !externallySelectedItemsAreInSyncRef.current; i++) {
5355
+ await wait(200);
5356
+ }
5357
+ }, []);
5358
+ const startCellEditing = React.useCallback(async ({ rowId, colId }) => {
4970
5359
  if (!gridApi)
4971
5360
  return;
4972
5361
  const colDef = gridApi.getColumnDef(colId);
4973
- if (!colDef)
5362
+ if (!colDef) {
4974
5363
  return;
4975
- prePopupOps();
5364
+ }
4976
5365
  const rowNode = gridApi.getRowNode(`${rowId}`);
4977
5366
  if (!rowNode) {
4978
5367
  return;
4979
5368
  }
4980
- if (!rowNode.isSelected()) {
5369
+ prePopupOps();
5370
+ const shouldSelectNode = !rowNode.isSelected();
5371
+ if (shouldSelectNode) {
5372
+ externallySelectedItemsAreInSyncRef.current = false;
4981
5373
  rowNode.setSelected(true, true);
5374
+ await waitForExternallySelectedItemsToBeInSync();
4982
5375
  }
4983
5376
  // Cell already being edited, so don't re-edit until finished
4984
- if (checkUpdating([colDef.field ?? ''], rowId)) {
5377
+ if (checkUpdating([colDef.field ?? colDef.colId ?? ''], rowId)) {
4985
5378
  return;
4986
5379
  }
4987
5380
  const rowIndex = rowNode.rowIndex;
4988
5381
  if (rowIndex != null) {
4989
- const focusAndEdit = () => {
4990
- gridApi.startEditingCell({
4991
- rowIndex,
4992
- colKey: colId,
4993
- });
4994
- };
4995
- lodashEs.defer(focusAndEdit);
5382
+ lodashEs.defer(() => {
5383
+ !gridApi.isDestroyed() &&
5384
+ gridApi.startEditingCell({
5385
+ rowIndex,
5386
+ colKey: colId,
5387
+ });
5388
+ });
4996
5389
  }
4997
- }, [checkUpdating, gridApi, prePopupOps]);
5390
+ }, [checkUpdating, gridApi, prePopupOps, waitForExternallySelectedItemsToBeInSync]);
4998
5391
  /**
4999
5392
  * This differs from stopEdit in that it will also invoke cellEditingCompleteCallback
5000
5393
  */
@@ -5009,12 +5402,12 @@ const GridContextProvider = (props) => {
5009
5402
  /**
5010
5403
  * Returns true if an editable cell on same row was selected, else false.
5011
5404
  */
5012
- const selectNextEditableCell = React.useCallback((tabDirection) => {
5405
+ const selectNextEditableCell = React.useCallback(async (tabDirection) => {
5013
5406
  // Pretend it succeeded to prevent unwanted cellEditingCompleteCallback
5014
5407
  if (!gridApi)
5015
5408
  return true;
5016
5409
  const focusedCellIsEditable = () => {
5017
- const focusedCell = gridApi.getFocusedCell();
5410
+ const focusedCell = gridApi.isDestroyed() ? null : gridApi.getFocusedCell();
5018
5411
  const nextColumn = focusedCell?.column;
5019
5412
  const nextColDef = nextColumn?.getColDef();
5020
5413
  const rowNode = focusedCell && gridApi.getDisplayedRowAtIndex(focusedCell?.rowIndex);
@@ -5025,8 +5418,22 @@ const GridContextProvider = (props) => {
5025
5418
  };
5026
5419
  // Just in case I've missed something, we don't want the loop to hang everything
5027
5420
  for (let maxIterations = 0; maxIterations < 50; maxIterations++) {
5421
+ if (gridApi.isDestroyed()) {
5422
+ return true;
5423
+ }
5028
5424
  const preRow = gridApi.getFocusedCell();
5029
- tabDirection === 1 ? gridApi.tabToNextCell() : gridApi.tabToPreviousCell();
5425
+ if (tabDirection === 1) {
5426
+ gridApi.tabToNextCell();
5427
+ }
5428
+ else {
5429
+ gridApi.tabToPreviousCell();
5430
+ }
5431
+ // If we don't wait the tab to next element won't work
5432
+ // I think this is due to the grid resizing
5433
+ await wait(150);
5434
+ if (gridApi.isDestroyed()) {
5435
+ return true;
5436
+ }
5030
5437
  const postRow = gridApi.getFocusedCell();
5031
5438
  if (preRow?.rowIndex !== postRow?.rowIndex || preRow?.column === postRow?.column) {
5032
5439
  // We didn't find an editable cell in the same row, or the cell column didn't change
@@ -5034,7 +5441,7 @@ const GridContextProvider = (props) => {
5034
5441
  break;
5035
5442
  }
5036
5443
  if (focusedCellIsEditable()) {
5037
- const focusedCell = gridApi?.getFocusedCell();
5444
+ const focusedCell = gridApi.getFocusedCell();
5038
5445
  if (focusedCell) {
5039
5446
  prePopupOps();
5040
5447
  gridApi.startEditingCell({
@@ -5053,19 +5460,23 @@ const GridContextProvider = (props) => {
5053
5460
  const selectedRows = props.selectedRows;
5054
5461
  let ok = false;
5055
5462
  await modifyUpdating(props.field ?? '', selectedRows.map((data) => data.id), async () => {
5463
+ // MATT Disabled I don't believe these are needed anymore
5464
+ // I've left them here just in case they are
5056
5465
  // Need to refresh to get spinners to work on all rows
5057
- gridApi.refreshCells({ rowNodes: props.selectedRows, force: true });
5466
+ // gridApi.refreshCells({ rowNodes: props.selectedRows as RowNode[], force: true });
5058
5467
  ok = await fnUpdate(selectedRows).catch((ex) => {
5059
5468
  console.error('Exception during modifyUpdating', ex);
5060
5469
  return false;
5061
5470
  });
5062
5471
  });
5472
+ // MATT Disabled I don't believe these are needed anymore
5473
+ // I've left them here just in case they are
5063
5474
  // async processes need to refresh their own rows
5064
- gridApi.refreshCells({ rowNodes: selectedRows, force: true });
5475
+ // gridApi.refreshCells({ rowNodes: selectedRows as RowNode[], force: true });
5065
5476
  if (ok) {
5066
5477
  const cell = gridApi.getFocusedCell();
5067
5478
  if (cell && gridApi.getFocusedCell() == null) {
5068
- gridApi.setFocusedCell(cell.rowIndex, cell.column);
5479
+ !gridApi.isDestroyed && gridApi.setFocusedCell(cell.rowIndex, cell.column);
5069
5480
  }
5070
5481
  // This is needed to trigger postSortRowsHook
5071
5482
  gridApi.refreshClientSideRowModel();
@@ -5080,7 +5491,7 @@ const GridContextProvider = (props) => {
5080
5491
  postPopupFocusedCell &&
5081
5492
  prePopupFocusedCell.current.rowIndex == postPopupFocusedCell.rowIndex &&
5082
5493
  prePopupFocusedCell.current.column.getColId() == postPopupFocusedCell.column.getColId()) {
5083
- if (!tabDirection || !selectNextEditableCell(tabDirection)) {
5494
+ if (!tabDirection || !(await selectNextEditableCell(tabDirection))) {
5084
5495
  cellEditingCompleteCallbackRef.current && cellEditingCompleteCallbackRef.current();
5085
5496
  }
5086
5497
  }
@@ -5095,17 +5506,6 @@ const GridContextProvider = (props) => {
5095
5506
  console.error(ex);
5096
5507
  }
5097
5508
  }, 50), [gridApi]);
5098
- // waitForExternallySelectedItemsToBeInSync can't use the state as it won't be updated during function execution
5099
- const externallySelectedItemsAreInSyncRef = React.useRef(false);
5100
- React.useEffect(() => {
5101
- externallySelectedItemsAreInSyncRef.current = externallySelectedItemsAreInSync;
5102
- }, [externallySelectedItemsAreInSync]);
5103
- const waitForExternallySelectedItemsToBeInSync = React.useCallback(async () => {
5104
- // Wait for up to 5 seconds
5105
- for (let i = 0; i < 5000 / 200 && !externallySelectedItemsAreInSyncRef.current; i++) {
5106
- await wait(200);
5107
- }
5108
- }, []);
5109
5509
  const onFilterChanged = React.useMemo(() => debounce(() => {
5110
5510
  // This is terrible, but there's no other way for me to check whether a filter has changed the grid
5111
5511
  const getDisplayedRowsHash = () => {
@@ -5428,7 +5828,6 @@ exports.GridFormSubComponentTextArea = GridFormSubComponentTextArea;
5428
5828
  exports.GridFormSubComponentTextInput = GridFormSubComponentTextInput;
5429
5829
  exports.GridFormTextArea = GridFormTextArea;
5430
5830
  exports.GridFormTextInput = GridFormTextInput;
5431
- exports.GridHeaderSelect = GridHeaderSelect;
5432
5831
  exports.GridIcon = GridIcon;
5433
5832
  exports.GridLoadableCell = GridLoadableCell;
5434
5833
  exports.GridNoRowsOverlay = GridNoRowsOverlay;
@@ -5473,7 +5872,6 @@ exports.bearingNumberParser = bearingNumberParser;
5473
5872
  exports.bearingRangeValidator = bearingRangeValidator;
5474
5873
  exports.bearingStringValidator = bearingStringValidator;
5475
5874
  exports.bearingValueFormatter = bearingValueFormatter;
5476
- exports.clickInputWhenContainingCellClicked = clickInputWhenContainingCellClicked;
5477
5875
  exports.convertDDToDMS = convertDDToDMS;
5478
5876
  exports.downloadCsvUseValueFormattersProcessCellCallback = downloadCsvUseValueFormattersProcessCellCallback;
5479
5877
  exports.findParentWithClass = findParentWithClass;