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